在Go语⾔中使⽤JSON(去掉空字段)Encode
将⼀个对象编码成JSON数据,接受⼀个interface{}对象,返回[]byte和error:
func Marshal(v interface{}) ([]byte, error)
Marshal函数将会递归遍历整个对象,依次按成员类型对这个对象进⾏编码,类型转换规则如下:
bool类型转换为JSON的Boolean
整数,浮点数等数值类型转换为JSON的Number
string 转换为JSON的字符串(带""引号)
struct 转换为JSON的Object,再根据各个成员的类型递归打包
数组或切⽚转换为JSON的Array
[]byte 会先进⾏base64编码然后转换为JSON字符串
map 转换为JSON的Object,key必须是string
interface{} 按照内部的实际类型进⾏转换
nil 转为JSON的null
channel,func等类型会返回UnsupportedTypeError
[plain]
1. type ColorGroup struct {
2.    ID    int
3.    Name  string
4.    Colors []string
5. }
6. group := ColorGroup{
7.    ID:    1,
8.    Name:  "Reds",
9.    Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
10. }
11. b, err := json.Marshal(group)
12. if err != nil {
13.    fmt.Println("error:", err)
14. }
15. os.Stdout.Write(b)
16.
17. Output:
18. {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
Decode
将JSON数据解码
func Unmarshal(data []byte, v interface{}) error
类型转换规则和上⾯的规则类似
[plain]
1. var jsonBlob = []byte(`[
2.    {"Name": "Platypus", "Order": "Monotremata"},
3.    {"Name": "Quoll",    "Order": "Dasyuromorphia"}
4. ]`)
5. type Animal struct {
6.    Name  string
7.    Order string
8. }
9. var animals []Animal
10. err := json.Unmarshal(jsonBlob, &animals)
11. if err != nil {
12.    fmt.Println("error:", err)
13. }
14. fmt.Printf("%+v", animals)
15.
16. Output:
17. [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
结构体
结构体必须是⼤写字母开头的成员才会被JSON处理到,⼩写字母开头的成员不会有影响。
Mashal时,结构体的成员变量名将会直接作为JSON Object的key打包成JSON;Unmashal时,会⾃动匹配对应的变量名进⾏赋值,⼤⼩写不敏感。
Unmarshal时,如果JSON中有多余的字段,会被直接抛弃掉;如果JSON缺少某个字段,则直接忽略不对结构体中变量赋值,不会报错。[plain]
1. type Message struct {
2.    Name  string
3.    Body  string
4.    Time  int64
5.    inner string
6. }
7.
8. var m = Message{
9.    Name:  "Alice",
10.    Body:  "Hello",
11.    Time:  1294706395881547000,
12.    inner: "ok",
13. }
14. b := []byte(`{"nAmE":"Bob","Food":"Pickle", "inner":"changed"}`)
15.
16. err := json.Unmarshal(b, &m)
17. if err != nil {
18.    fmt.Printf(err.Error())
19.    return
20. }
21. fmt.Printf("%v", m)
22.
23. Output:
24. {Bob Hello 1294706395881547000 ok}
StructTag
如果希望⼿动配置结构体的成员和JSON字段的对应关系,可以在定义结构体的时候给成员打标签:
使⽤omitempty熟悉,如果该字段为nil或0值(数字0,字符串"",空数组[]等),则打包的JSON结果不会有这个字段。
[plain]
1. type Message struct {
2.    Name string `json:"msg_name"`      // 对应JSON的msg_name
3.    Body string `json:"body,omitempty"` // 如果为空置则忽略字段
4.    Time int64  `json:"-"`              // 直接忽略字段
5. }
6. var m = Message{
7.    Name: "Alice",
8.    Body: "",
9.    Time: 1294706395881547000,
10. }
11. data, err := json.Marshal(m)
12. if err != nil {
13.    fmt.Printf(err.Error())
14.    return
15. }
16. fmt.Println(string(data))
17.
18. Output:
19. {"msg_name":"Alice"}
更灵活地使⽤JSON
go语言字符串转数组
使⽤json.RawMessage
json.RawMessage其实就是[]byte类型的重定义。可以进⾏强制类型转换。
现在有这么⼀种场景,结构体中的其中⼀个字段的格式是未知的:
[plain]
1. type Command struct {
2.    ID  int
3.    Cmd  string
4.    Args *json.RawMessage
5. }
使⽤json.RawMessage的话,Args字段在Unmarshal时不会被解析,直接将字节数据赋值给Args。我们可以能先解包第⼀层的JSON数据,然后根据Cmd的值,再确定Args的具体类型进⾏第⼆次Unmarshal。
这⾥要注意的是,⼀定要使⽤指针类型*json.RawMessage,否则在Args会被认为是[]byte类型,在打包时会被打包成base64编码的字符串。
使⽤interface{}
interface{}类型在Unmarshal时,会⾃动将JSON转换为对应的数据类型:
JSON的boolean 转换为bool
JSON的数值转换为float64
JSON的字符串转换为string
JSON的Array 转换为[]interface{}
JSON的Object 转换为map[string]interface{}
JSON的null 转换为nil
需要注意的有两个。⼀个是所有的JSON数值⾃动转换为float64类型,使⽤时需要再⼿动转换为需要的int,int64等类型。第⼆个是JSON的object⾃动转换为map[string]interface{}类型,访问时直接⽤JSON Object的字段名作为key进⾏访问。再不知道JSON数据的格式时,可以使⽤interface{}。
⾃定义类型
如果希望⾃⼰定义对象的打包解包⽅式,可以实现以下的接⼝:
[plain]
1. type Marshaler interface {
2.    MarshalJSON() ([]byte, error)
3. }
4. type Unmarshaler interface {
5.    UnmarshalJSON([]byte) error
6. }
实现该接⼝的对象需要将⾃⼰的数据打包和解包。如果实现了该接⼝,json在打包解包时则会调⽤⾃定义的⽅法,不再对该对象进⾏其他处理。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。