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
最简单的情况
- 用
struct
定义出符合要求的类型对应 JSON 对象 - 如果非常简单,类型一致,可能只需要用数组和
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 判断控制逻辑对序列化的影响:
- 如果字段是 struct 类型,则该字段默认值就不会被判定为空,emitempty 失效
- 如果字段的值正好就是默认值,比如 int 类型值为 0 的时候,emitempty 会干掉这个字段
如有必要,解决方法就是改成指针的方式。
第三方库
更详细的对比参考《Go JSON 第三方库》。
参考资料与拓展阅读
- 微信公众号,Go 语言教程,Go 中 “omitempty” 的陷阱