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