Go 中的 json 处理

less than 1 minute read

序列化

  • 序列化 struct 时,json.Marshal 方法可接收结构体或者结构体的指针。 结构体内的field 也可以是指针或者接口
    • 如果是指针,那么指针指向的值会用作序列化
    • 如果是接口,那么接口的具体值会用作序列化。
  • 只会序列化 exported fields

  • 自定义JSON序列化规则:通过实现 json.Marshaler 或者 encoding.TextMarshaler 接口:
type Marshaler interface {
    MarshalJSON() ([]byte, error)
}

type TextMarshaler interface {
    MarshalText() (text []byte, err error)
}
  • 常用的 struct tag option:

    • omitempty:打上了这个标签的 field 如果值是“空”的,那么就不会被序列化。“空”的含义:
      • bool:false
      • numeric:0
      • pointer:nil
      • interface:nil
      • array,slice,map,string:空的数组、切片、映射、字符串
    • string:序列化时转换为 string。该标签仅适用于 string、float、int、bool 类型的 field
    • -:表示这个 field 在序列化时会被忽略(不管是否为“空”)
    • -,:表示这个 field 在序列化时的 JSON key 就是 -

反序列化

  • 使用 json.Valid 函数验证输入是否是合法的 JSON: func Valid(data []byte) bool

  • 使用 json.Unmarsal 函数将 JSON 转化为 map 或者 structfunc Unmarshal(data []byte, v interface{}) error。函数参数中的 v指针,正如godoc中所述:”If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError.

  • 反序列化时:会忽略结构体中的 unexported fields;会忽略 data 中有的而结构体中没有的字段;对于 data 中没有而结构体中有的字段,结果是该字段的零值

  • 带有 - tag option 的字段,在反序列化时会被忽略。

  • 有时候可以采用一种“简单粗暴”方法,即将 v 当作 &interface{} 传入,也可以正确反序列化

  • 自定义反序列化规则:实现 json.Unmarshaler 接口或者 encoding.TextUnmarshaler 接口(仅对于string类型的JSON value)

    type Unmarshaler interface {
        UnmarshalJSON([]byte) error
    }
    type TextUnmarshaler interface {
        UnmarshalText(text []byte) error
    }
    

Encoder 和 Decoder

这是两个“互逆”的过程:

  • 使用 Encoder:
    1. 通过 io.Writer 构造一个 *Encoder: func NewEncoder(w io.Writer) *Encoder
    2. 调用 Encode 方法将结构体、map等JSON序列化并写入上述的 Writer 对象:func (enc *Encoder) Encode(v interface{}) error
  • 使用 Decoder:
    1. 通过 io.Reader 构造一个 *Decoderfunc NewDecoder(r io.Reader) *Decoder
    2. 调用 Decode 方法读取 Reader 的内容(每次读一行)并对其做JSON反序列化:func (dec *Decoder) Decode(v interface{}) error

更多

更详细内容和范例,见 Working with JSON in Go

Tags: ,

Categories:

Updated:

Comments