Go语言处理Json数据

JSON 是目前最为流行的序列化手段,Go 语言内置 encoding/json 包用于 JSON 序列化 / 反序列化 操作。本文以详细代码示例,演示 encoding/json 包的使用方式。

序列化

对于已有类型,序列化只需一行代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 序列化操作,结果如下:

1
{"Name":"bar","Value":1}

静态序列化

为了生成 JSON 数据,如果类型未定义,则需要先定义新的数据类型。

例如,为了临时生成以下两种不同格式的 JSON 数据:

1
2
{"Type":"map","Data":{"Bar":1,"Foo":2}}
{"Type":"list","Data":[{"Name":"Bar","Value":1},{"Name":"Foo","Value":2}]}

可以先定义以下数据类型:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
type Pair struct {
    Name string
    Value int
}

type Map struct {
    Bar int
    Foo int
}

type Message struct {
    Type string
    Data Object
}

然后,初始化数据并序列化:

1
2
3
4
5
6
7
content, err := json.Marshal(Message{
	Type: "map",
	Data: Map{
		Bar: 1,
		Foo: 2,
	},
})

这便是 静态序列化 方式,为了生成 JSON 数据而定义新的数据类型,好比用牛刀杀鸡。 接着,在 动态序列化 一节,介绍一种灵活构建 JSON 数据的方法,更加简便。

自定义字段

序列化结构体,字段名默认与结构体一致。 结构体字段名通过首字母大小写控制访问,因此有时并不满足需要。 例如,结构体中的字段名是驼峰风格,而 JSON 字段名却要求用小写字母以及下划线…… 这时,只能为结构体字段打上辅助标签:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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"`
}

这样一来,序列化结果便满足要求了:

1
2
{"type":"map","data":{"bar":1,"value":2}}
{"type":"list","data":[{"name":"Bar","value":1},{"name":"Foo","value":2}]}

动态序列化

Python 之类的动态类型语言,我们可以非常自由地组织数据,随时随地:

1
2
3
4
5
6
7
json.dumps({
    "type": "map",
    "data": {
        "bar": 1,
        "foo": 2,
    },
})

然而, Go 不是动态类型语言,是不是就没有办法实现动态序列化了呢?

当然不是了,我们可以通过空接口实现。 首先定义几种基本类型:

1
2
3
4
5
type Object interface {}
type Array []Object

type JsonObject map[string]Object
type JsonArray Array

其中,Object 可以是任意类型;Array 可以是任意类型组成的 数组JsonOject 是一个 映射表 ,键为字符类型,值可以是任意类型;JsonArrayArray 相同。

有了这些基本类型,我们也可以非常灵活的组装数据,同样随时随地:

1
2
3
4
5
6
7
content, err := json.Marshal(JsonObject{
	"type": "map",
	"data": JsonObject{
		"bar": 1,
		"foo": 2,
	},
})

组装另一种数据类型:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
content, err = json.Marshal(JsonObject{
	"type": "list",
	"data": Array{
		JsonObject{
			"name": "bar",
			"value": 1,
		},
		JsonObject{
			"name": "foo",
			"value": 2,
		},
	},
})

【小菜学Go语言】系列文章首发于公众号【小菜学编程】,敬请关注:

【小菜学Go语言】系列文章首发于公众号【小菜学编程】,敬请关注: