Json序列化
JSON 是目前最为流行的序列化手段, Go 语言内置 encoding/json包用于 JSON序列化 / 反序列化 操作。本文以详细代码示例,演示 encoding/json 包的使用方式。
序列化
对于已有类型,序列化只需一行代码:
/_src/practices/jsonify/quick-marshal.go
- package main
- import (
- "encoding/json"
- "fmt"
- "log"
- )
- type Pair struct {
- Name string
- Value int
- }
- func main() {
- pair := Pair{
- Name: "bar",
- Value: 1,
- }
- content, err := json.Marshal(pair)
- if err == nil {
- fmt.Printf("%s\n", content)
- } else {
- log.Fatal(pair)
- }
- }
例子第 9-12 行,定义了一个 Pair 类型,包含两个字段;第 15-18 行,定义了一个 Pair 变量并初始化;第 20 行对该变量进行 JSON 序列化操作,结果如下:
- {"Name":"bar","Value":1}
静态序列化
为了生成 JSON 数据,如果类型未定义,则需要先定义新的数据类型。
例如,为了临时生成以下两种不同格式的 JSON 数据:
- {"Type":"map","Data":{"Bar":1,"Foo":2}}
- {"Type":"list","Data":[{"Name":"Bar","Value":1},{"Name":"Foo","Value":2}]}
可以先定义以下数据类型:
/_src/practices/jsonify/static-marshal.go
- type Pair struct {
- Name string
- Value int
- }
- type Map struct {
- Bar int
- Foo int
- }
- type Message struct {
- Type string
- Data Object
- }
然后,初始化数据并序列化:
/_src/practices/jsonify/static-marshal.go
- content, err := json.Marshal(Message{
- Type: "map",
- Data: Map{
- Bar: 1,
- Foo: 2,
- },
- })
这便是 静态序列化 方式,为了生成 JSON 数据而定义新的数据类型,好比用牛刀杀鸡。接着,在 动态序列化 一节,介绍一种灵活构建 JSON 数据的方法,更加简便。
自定义字段名
序列化结构体,字段名默认与结构体一致。结构体字段名通过首字母大小写控制访问,因此有时并不满足需要。例如,结构体中的字段名是驼峰风格,而 JSON 字段名却要求用小写字母以及下划线……这时,只能为结构体字段打上辅助标签:
/_src/practices/jsonify/static-marshal-with-tags.go
- type Pair struct {
- Name string `json:"name"`
- Value int `json:"value"`
- }
- type Map struct {
- Bar int `json:"bar"`
- Foo int `json:"value"`
- }
- type Message struct {
- Type string `json:"type"`
- Data Object `json:"data"`
- }
这样一来,序列化结果便满足要求了:
- {"type":"map","data":{"bar":1,"value":2}}
- {"type":"list","data":[{"name":"Bar","value":1},{"name":"Foo","value":2}]}
动态序列化
像 Python 之类的动态类型语言,我们可以非常自由地组织数据,随时随地:
- json.dumps({
- "type": "map",
- "data": {
- "bar": 1,
- "foo": 2,
- },
- })
然而, Go 不是动态类型语言,是不是就没有办法实现动态序列化了呢?
当然不是了,我们可以通过空接口实现。首先定义几种基本类型:
/_src/practices/jsonify/free-marshal.go
- type Object interface {}
- type Array []Object
- type JsonObject map[string]Object
- type JsonArray Array
其中, Object 可以是任意类型;Array 可以是任意类型组成的 数组 ;JsonOject 是一个 映射表 ,键为字符类型,值可以是任意类型;JsonArray 与 Array 相同。
有了这些基本类型,我们也可以非常灵活的组装数据,同样随时随地:
/_src/practices/jsonify/free-marshal.go
- content, err := json.Marshal(JsonObject{
- "type": "map",
- "data": JsonObject{
- "bar": 1,
- "foo": 2,
- },
- })
组装另一种数据类型:
/_src/practices/jsonify/free-marshal.go
- content, err = json.Marshal(JsonObject{
- "type": "list",
- "data": Array{
- JsonObject{
- "name": "bar",
- "value": 1,
- },
- JsonObject{
- "name": "foo",
- "value": 2,
- },
- },
- })
下一步
订阅更新,获取更多学习资料,请关注我们的 微信公众号 :