本文将说明如何利用 Go 语言将 JSON 解析为结构体和数组,如果解析 JSON 的嵌入对象,如何将 JSON 的自定义属性名称映射到结构体,如何解析非结构化的 JSON 字符串。
JSON 解析为结构体
JSON 的结构是 key-value,最直观的就是将 JSON 解析为结构体,如下 JSON :
{ "name": yuzhou1u, "age": 18 }
Go 语言中,提供了一个专门的包 encoding/json
,所以我们在使用这个 JSON 包之前需要在头文件导入:
package main import ( "encoding/json" "fmt" )
然后,我们需要定义一个 Go 语言的结构体以便我们能与 JSON 一一对应,比如在 JSON 中我们定义了姓名 name
和年龄 age
,所以需要定义一个结构体(命名可以随意,但最好通俗易懂)的字段与 JSON 字符串中的键相匹配:
type Person struct { Name string Age int }
然后使用 json.Umarshal()
函数来解析 JSON 字符串,完整代码如下:
package main import ( "encoding/json" "fmt" ) type Person struct { Name string Age int } func main() { var p Person jsonString := `{"name": "yuzhou1su", "age" : 18}` err := json.Unmarshal([]byte(jsonString), &p) if err == nil { fmt.Println(p.Name) fmt.Println(p.Age) } else { fmt.Println(err) } }
现在来解释一下上面 main 函数的代码:
- 定义一个 Person 的 p 对象
- 因为我们没有把文件系统使用上,所以是定义了一个
jsonString
的 JSON 数据 - 使用
json.Unmarshal()
函数能够解析 JSON 格式的数据。但需要将 JSON 字符串转换为字节切片,并将结果存储到 p 对象中。 使用需要使用 & 地址运算符传入人员的地址。 - 如果解析有效,则
json.Unmarshal()
函数返回 nil,您现在可以找到存储在 person 变量中的值。 - 确保将 Person 结构中每个字段的第一个字符大写。 如果字段名称以小写字母开头,则不会导出到当前包之外,并且字段对
json.Unmarshal()
函数不可见。
运行上述代码,打印在控制台中结果为:
yuzhou1su 18
JSON 解析为数组
通常 JSON 数据会包括一系列的对象数组,就像这样一个班级的数据:
[ { "id": 1, "name": "张三" "age": 20 }, { "id": 2, "name": "李翠花" "age": 18 }, { "id": 3, "name": "王老五" "age": 25 } ]
我们只需要定义一个 students[]
的数组,代码如下:
package main import ( "encoding/json" "fmt" ) type Student struct { Id int Name string Age int } func main() { var students []Student myClass := `[ { "id": 1, "name": "张三", "age": 20 }, { "id": 2, "name": "李翠花", "age": 18 }, { "id": 3, "name": "王老五", "age": 25 } ]` err := json.Unmarshal([]byte(myClass), &students) if err == nil { for _, student := range students { fmt.Print("\t\n", student.Id) fmt.Print("\t", student.Name) fmt.Print("\t", student.Age) } } else { fmt.Println(err) } }
使用 for...range
迭代数组,然后运行上述代码:
$ go run main.go 1 张三 20 2 李翠花 18 3 王老五 25
解析 JSON 嵌入对象
JSON 字符串有时包含嵌入对象,比如:
{ "name": "yuzhou1su", "age": 18, "address": { "road": "renmin south road", "street": "123 street", "city": "cs", "province": "hn", "country": "cn" } }
address
就是属于内嵌对象,我们同样需要创建另一个 Address
结构体:
package main import ( "encoding/json" "fmt" ) type Person struct { Name string Age int Address struct { Road string Street string City string Province string Country string } } func main() { var p Person jsonString := ` { "name": "yuzhou1su", "age": 18, "address": { "road": "renmin south road", "street": "123 street", "city": "cs", "province": "hn", "country": "cn" } }` err := json.Unmarshal([]byte(jsonString), &p) if err == nil { fmt.Println(p.Name) fmt.Println(p.Age) fmt.Println(p.Address.Road) fmt.Println(p.Address.Street) fmt.Println(p.Address.City) fmt.Println(p.Address.Province) fmt.Println(p.Address.Country) } else { fmt.Println(err) } }
输出结果:
yuzhou1su 18 renmin south road 123 street cs hn cn