TOC

Golang JSON

Golang 有一个 encoding/json 标准库,在多数情况下已经够用了。

注意:因为 Golang 是一种静态类型的语言,所以解析 JSON 字符串必须了解里面的数据结构。
如果是用惯了 JS、Python、PHP 等动态语言的话,到这里会有些郁闷,怎么解析一个 JSON 还这么复杂。

接口

  • 序列化
    • func Marshal(v interface{}) ([]byte, error)
    • func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
    • func NewEncoder(w io.Writer) *Encoder
  • 反序列化
    • func Unmarshal(data []byte, v interface{}) error
    • func NewDecoder(r io.Reader) *Decoder

最简单的情况

  1. struct 定义出符合要求的类型对应 JSON 对象
  2. 如果非常简单,类型一致,可能只需要用数组和 map 就可以了
package main

import (
    "encoding/json"
    "fmt"
)


func main() {
    json_str := `[{"name":"admin","gender":"male"},{"name":"staff001","gender":"female"}]`
    json_bytes := []byte(json_str)
    json_map := make([](map[string]string), 10)
    err := json.Unmarshal(json_bytes, &json_map)
    if err != nil {
        fmt.Println("UmarshalError:", err)
        return
    }
    fmt.Println(json_map)
    s, err := json.Marshal(json_map)
    fmt.Println(string(s))
}

动态 Key

延迟解析 json.RawMessage

type Responce {
    code string
    msg  string
    data *json.RawMessage
}

omitempty

type User struct {
    Name     string `json:"name"`
    Age      int    `json:"age,omitempty"`
    Password string `json:"-"` // JSON 序列化时忽略该字段
}

开发者应该清楚 omitempty 判断控制逻辑对序列化的影响:

  1. 如果字段是 struct 类型,则该字段默认值就不会被判定为空,emitempty 失效
  2. 如果字段的值正好就是默认值,比如 int 类型值为 0 的时候,emitempty 会干掉这个字段

如有必要,解决方法就是改成指针的方式。

第三方库

更详细的对比参考《Go JSON 第三方库》。

参考资料与拓展阅读