摘要
本文部分内容来源于网络,个人收集整理,请勿传播
JSON(Javascript Object Notation, JS 对象标记)是一种轻量级的数据交换语言,它基于 ECMAScript 规范的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON与XML最大的不同在于XML是一个完整的标记语言,而JSON不是。JSON由于比XML更小、更快,更易解析,以及浏览器的內建快速解析支持,使得其更适用于网络数据传输领域。
encoding/json
Marshal解析输出json
针对JSON的输出,我们在定义struct tag的时候需要注意几点:
- 字段的tag是“-”,那么这个字段不会输出到JSON
- tag中带有自定义名称,那么这个自定义名称会出现在JSON的字段名中
- tag中如果带有“omitempty”选项,那么如果该字段值为空,就不会输出到JSON串中
- 如果字段类型是bool,string,int,int64等,而tag中带有“,string”选项,那么这个字段在输出到JSON的时候会把该字段对应的值转换成JSON字符串
1 | func Marshal(v interface{})([]byte, error) |
简单应用
1 | package main |
- 只要是可导出成员(变量首字母大写),都可以转成json。因成员变量sex是不可导出的,故无法转成json。
- 如果变量打上了json标签,如Name旁边的
json:"name"
,那么转化成的json key就用该标签“name”,否则取变量名作为key,如“Age”,“HIgh”。 - bool类型也是可以直接转换为json的value值。Channel, complex 以及函数不能被编码json字符串。当然,循环的数据结构也不行,它会导致marshal陷入死循环。
- 指针变量,编码时自动转换为它所指向的值,如cla变量。
(当然,不传指针,Stu struct的成员Class如果换成Class struct类型,效果也是一模一样的。只不过指针更快,且能节省内存空间。)
interface
1 | package main |
slice
https://blog.csdn.net/zxy_666/article/details/80173288
1 | //正确示范 |
输出JSON数据串
1 | // generalJson |
Marshal函数只有在转换成功的时候才会返回数据,在转换的过程中我们需要注意几点:
- JSON对象只支持string作为key,所以要编码一个map,那么必须是
map[string]T
这种类型(T是Go语言中任意的类型) - Channel,complex和function是不能被编码成JSON的
- 嵌套的数据时不能编码的,不然会让JSON编码进入死循环
- 指针在编码的时候会输出指针指向的内容,而空指针会输出null
1 | // jsontest.go |
Unmarshal 解析json
1 | func Unmarshal(data [] byte, v interface{}) error |
这个函数会把传入的 data 作为一个JSON来进行解析,解析后的数据存储在参数 v 中。这个参数 v 也是任意类型的参数(但一定是一个类型的指针),原因是我们在是以此函数进行JSON 解析的时候,这个函数不知道这个传入参数的具体类型,所以它需要接收所有的类型。
1 | package main |
Encoders and Decoders
1 | func NewDecoder(r io.Reader) *Decoder |
1 | package main |
解析到结构体
1 | // json.go |
- 先定义了与JSON数据对应的结构体,以及与数组对应的slice
- 字段名对应JSON里面的key
- 解析:如果key是Foo
- 在结构体里面查找含有Foo的可导出的struct字段(首字母大写)
- 其次查找字段名是Foo的导出字段
- 最后查找类似FOO或者FoO这样的除了首字母之外其他大小写不敏感的导出字段
- 能够被赋值的字段必须是可导出字段(即首字母大写)
- 同时JSON解析的时候只会解析能找到的字段,如果找不到的字段会被忽略
- 这样的一个好处是:当你接收到一个很大的JSON数据结构而你却只想获取其中的部分数据的时候,你只需将你想要的数据对应的字段名大写
解析到interface
我们知道interface{}
可以用来存储任意数据类型的对象,这种数据结构正好用于存储解析的未知结构的json数据的结果。
JSON包中采用map[string]interface{}
和[]interface{}
结构来存储任意的JSON对象和数组。Go类型和JSON类型的对应关系如下:
- bool: JSON booleans
- float64: JSON numbers
- string: JSON strings
- nil: JSON null
1 | // tointer.go |
通过interface{}
与type assert
的配合,我们就可以解析未知结构的JSON函数了
在net/http
中应用json
1 | package main |
完整例子
1 | package main |
go-simplejson
bitly公司开源了一个叫做simplejson
的包,在处理未知结构体的JSON时相当方便,地址
1 | j, err := simplejson.NewJson([]byte(flow)) |
json-iterator/go
解析速度最快的json解析器,它最多能比普通的解析器快 10 倍之多,即使在数据绑定的用法下也有同样的性能优势。
安装
1 | go get github.com/json-iterator/go |
Marshal结构体解析到json
1 | package main |
Unmarshal解析json到结构体
1 | package main |
jsoniter.Get
解析不固定结构json
1 | package main |
NewDecoder
1 | package main |
对比json
https://www.cnblogs.com/wangzhao765/p/9662331.html
json 文件
1 | // json01.json |
对比
1 | package main |
细节对比
1 | package service |