在现代开发中,JSON是 API 数据交换的“通用语言”。 无论是 Web 接口、配置文件,还是微服务间通信,JSON 都是不可或缺的一环。而在 Go 语言中,标准库已经为我们准备好了强大的工具 —— encoding/json 包,让你轻松实现 数据序列化(Marshal) 和 反序列化(Unmarshal) 。
1、什么是序列化与反序列化?
- 序列化(Marshal) : 把 Go 的结构体或其他数据类型转换成 JSON 格式字符串。 🌰 类似于 “打包寄快递”。
- 反序列化(Unmarshal) : 把 JSON 字符串转换回 Go 的数据结构。 🌰 类似于 “拆包还原内容”。
2、序列化(Marshal)示例
package main
import (
"encoding/json"
"fmt"
)
//默认情况下,字段名必须首字母大写(即导出字段),否则不会被编码。
type Car struct {
Name string `json:"name"` //使用结构体标签 json:"字段名" 可自定义输出键名;
Class string `json:"class"`
Color string `json:"color"`
}
func main() {
u := Car{Name: "X5", Class: "BMW", Color: "白色"}
// 将结构体转为 JSON
jsonData, err := json.Marshal(u) //json.Marshal() 会返回一个 []byte 类型的 JSON 数据
if err != nil {
fmt.Println("序列化出错:", err)
return
}
fmt.Println(string(jsonData))
}
3、反序列化(Unmarshal)示例
package main
import (
"encoding/json"
"fmt"
)
type Car struct {
Name string `json:"name"`
Class string `json:"class"`
Color string `json:"color"`
}
func main() {
jsonStr := `{"name":"X5","class":"BMW","color":"白色"}`
var c Car
//json.Unmarshal() 会根据 JSON 键名匹配结构体的字段;
err := json.Unmarshal([]byte(jsonStr), &c) //要注意传入的是 &c(结构体指针)
if err != nil {
fmt.Println(`反序列化出错:`, err)
return
}
fmt.Println("解析结果:%+v\n", c)
}
4、漂亮输出json
package main
import (
"encoding/json"
"fmt"
)
type Car struct {
Name string `json:"name"`
Class string `json:"class"`
Color string `json:"color"`
}
func main() {
c := Car{Name: "X5", Class: "别摸我", Color: "白色"}
data, _ := json.MarshalIndent(c, "", " ")
fmt.Println(string(data))
}
5、灵活类型:map 与 interface{}
有时候我们无法知道JSON的结构,这时可以用动态解析
5.1 解析到map
var data map[string]interface{}
json.Unmarshal([]byte(jsonStr),&data)
fmt.Println(data[`name`]) // X5
fmt.Println(data[`color`]) // 白色
5.2 直接从map构建JSON
m := map[string]interface{}{
"status": "ok",
"count": 3,
}
b, _ := json.Marshal(m)
fmt.Println(string(b))//{"count":3,"status":"ok"}
6、小技巧与注意事项
type Car struct {
Name string `json:"car_name"` // 重命名字段
Fridge *string `json:"fridge"` // 指针代表可选字段,冰箱可有可无
SecretKey string `json:"-"` // 忽略字段,不对外展示
Color string `json:"color,omitempty"` // 零值省略,也就是当为空的时候忽略
Music interface{} `json:"music"` // 使用interface{}表示任意数据
Ability []struct{} `json:"ability"` // 可以绑定到结构体
EnginSystem []map[string]any `json:"enginSystem"` //可以绑定到map,any也代表interface{}
}
一句话人生哲理:懂得用别人的语言表达自己,也能用自己的心理解别人。这,就是人生版的encoding/json。
源码地址
1、公众号“Codee君”回复“源码”获取源码
如果您喜欢这篇文章,请您(点赞、分享、亮爱心),万分感谢!