非零基础自学Golang
文章目录
- 非零基础自学Golang
- 第11章 文件操作
- 11.3 处理JSON文件
- 11.3.1 编码JSON
第11章 文件操作
11.3 处理JSON文件
JSON(JavaScript Object Notation,JS对象简谱)是一种轻量级的数据交换格式。
JSON最初是属于JavaScript的一部分,后来由于其良好的可读性和便于快速编写的特性,现在已独立于语言,基本上所有的语言都支持JSON数据的编码和解码。特别是对于网络编程而言,JSON的重要性不言而喻。【确实】
JSON中的键都是字符串形式,值可以取任意类型。
它有以下三种结构:
- 值为字符串或数组类型:{“name”:“John”,“age”:20}
- JSON数组:[{“name”:" John",“age”:20},{“name”:“Tom”,“age”:21}]
- 值为对象类型:{“name”:" John ", “birthday”:{“month”:8,“day”:26}},类似于对象嵌套对象
其中,大括号“{}”用来描述一组“不同类型的无序键值对集合”,方括号“[]”用来描述一组“相同类型的有序数据集合”。
关于JSON的更多信息,可以访问JSON官方网址http://json.org/进行查阅。
我们先来看一个JSON样例,后面的程序都是基于这个样例编写的。
{
"name":"小丁",
"age":23,
"sex":true,
"birthday":"2022-12-05",
"company":"字节跳动",
"language":[
"Go",
"Java",
"Python"
]
}
11.3.1 编码JSON
标准库提供了encoding/json库来处理JSON。
编码JSON,即从其他的数据类型编码成JSON字符串,这个过程我们会使用如下的接口:
func Marshal(v interface{}) ([]byte, error)
Marshal函数返回interface{}类型的JSON编码,通常interface{}类型会使用map或者结构体。
为了让输出的JSON字符串更加直观,可以使用另一个JSON编码接口,对输出的JSON进行格式化操作。
func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
MarshalIndent类似于Marshal,但会使用缩进将输出格式化。我们可以使用map来创建最简单的JSON。
[ 动手写 11.3.1 ]
package main
import (
"encoding/json"
"fmt"
)
func main() {
// 创建一个map
m := make(map[string]interface{}, 6)
m["name"] = "小丁"
m["age"] = 23
m["sex"] = true
m["birthday"] = "2022-12-05"
m["company"] = "字节跳动"
m["language"] = []string{"Go", "Java", "Python"}
// 编码成JSON
result, _ := json.Marshal(m)
resultFormat, _ := json.MarshalIndent(m, "", " ")
fmt.Println("result = ", string(result))
fmt.Println("resultFormat = ", string(resultFormat))
}
运行结果
大多数情况下,我们会使用struct结构体来进行快速的JSON编码、解码,特别是在JSON解码时,使用struct会相当方便。
[ 动手写 11.3.2]
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
Sex bool `json:"sex"`
Birthday string `json:"birthday"`
Company string `json:"company,omitempty"`
Language []string `json:"language"`
}
func main() {
// 定义一个结构体变量
person := Person{"小丁", 23, true, "2022-12-05", "字节跳动", []string{"Go", "Java", "Python"}}
result, err := json.MarshalIndent(person, "", " ")
if err != nil {
fmt.Println(err)
}
fmt.Println("result = ", string(result))
}
运行结果
在定义struct字段的时候,可以在字段后面添加标签来控制编码/解码的过程:是否要编码或解码某个字段,JSON中的字段名称是什么。
可以选择的控制字段有三种:
- -:不要解析这个字段。
- omitempty:当字段为空(默认值)时,不要解析这个字段。比如false、0、nil、长度为0的array、map、slice、string。
- FieldName:当解析JSON的时候,使用这个名字。
在动手写11.3.2中,“json:"name"
”就是定义的第三类标签,表示将Name属性的key值解析为name。
Name string `json:"name"`