Go 中的 json 处理
序列化
- 序列化 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或者struct:func 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:
- 通过
io.Writer构造一个*Encoder:func NewEncoder(w io.Writer) *Encoder - 调用
Encode方法将结构体、map等JSON序列化并写入上述的Writer对象:func (enc *Encoder) Encode(v interface{}) error
- 通过
- 使用 Decoder:
- 通过
io.Reader构造一个*Decoder:func NewDecoder(r io.Reader) *Decoder - 调用
Decode方法读取Reader的内容(每次读一行)并对其做JSON反序列化:func (dec *Decoder) Decode(v interface{}) error
- 通过
更多
更详细内容和范例,见 Working with JSON in Go
Comments