欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

在Go语言中使用JSON的方法

程序员文章站 2022-07-10 17:58:28
encode 将一个对象编码成json数据,接受一个interface{}对象,返回[]byte和error: func marshal(v interface...

encode

将一个对象编码成json数据,接受一个interface{}对象,返回[]byte和error:

func marshal(v interface{}) ([]byte, error)

marshal函数将会递归遍历整个对象,依次按成员类型对这个对象进行编码,类型转换规则如下:

bool类型 转换为json的boolean
整数,浮点数等数值类型 转换为json的number
string 转换为json的字符串(带""引号)
struct 转换为json的object,再根据各个成员的类型递归打包
数组或切片 转换为json的array
[]byte 会先进行base64编码然后转换为json字符串
map 转换为json的object,key必须是string
interface{} 按照内部的实际类型进行转换
nil 转为json的null
channel,func等类型 会返回unsupportedtypeerror

type colorgroup struct { 
 id  int 
 name string 
 colors []string 
} 
group := colorgroup{ 
 id:  1, 
 name: "reds", 
 colors: []string{"crimson", "red", "ruby", "maroon"}, 
} 
b, err := json.marshal(group) 
if err != nil { 
 fmt.println("error:", err) 
} 
os.stdout.write(b) 
output: 
{"id":1,"name":"reds","colors":["crimson","red","ruby","maroon"]} 

decode

将json数据解码

func unmarshal(data []byte, v interface{}) error

类型转换规则和上面的规则类似

var jsonblob = []byte(`[ 
 {"name": "platypus", "order": "monotremata"}, 
 {"name": "quoll", "order": "dasyuromorphia"} 
]`) 
type animal struct { 
 name string 
 order string 
} 
var animals []animal 
err := json.unmarshal(jsonblob, &animals) 
if err != nil { 
 fmt.println("error:", err) 
} 
fmt.printf("%+v", animals) 
output: 
[{name:platypus order:monotremata} {name:quoll order:dasyuromorphia}]

结构体

结构体必须是大写字母开头的成员才会被json处理到,小写字母开头的成员不会有影响。

mashal时,结构体的成员变量名将会直接作为json object的key打包成json;unmashal时,会自动匹配对应的变量名进行赋值,大小写不敏感。

unmarshal时,如果json中有多余的字段,会被直接抛弃掉;如果json缺少某个字段,则直接忽略不对结构体中变量赋值,不会报错。

type message struct { 
 name string 
 body string 
 time int64 
 inner string 
} 
var m = message{ 
 name: "alice", 
 body: "hello", 
 time: 1294706395881547000, 
 inner: "ok", 
} 
b := []byte(`{"name":"bob","food":"pickle", "inner":"changed"}`) 
err := json.unmarshal(b, &m) 
if err != nil { 
 fmt.printf(err.error()) 
 return 
} 
fmt.printf("%v", m) 
output: 
{bob hello 1294706395881547000 ok} 

 structtag

如果希望手动配置结构体的成员和json字段的对应关系,可以在定义结构体的时候给成员打标签:

使用omitempty熟悉,如果该字段为nil或0值(数字0,字符串"",空数组[]等),则打包的json结果不会有这个字段。

type message struct { 
 name string `json:"msg_name"`  // 对应json的msg_name 
 body string `json:"body,omitempty"` // 如果为空置则忽略字段 
 time int64 `json:"-"`    // 直接忽略字段 
} 
var m = message{ 
 name: "alice", 
 body: "", 
 time: 1294706395881547000, 
} 
data, err := json.marshal(m) 
if err != nil { 
 fmt.printf(err.error()) 
 return 
} 
fmt.println(string(data)) 
output: 
{"msg_name":"alice"} 

更灵活地使用json

使用json.rawmessage

json.rawmessage其实就是[]byte类型的重定义。可以进行强制类型转换。

现在有这么一种场景,结构体中的其中一个字段的格式是未知的:

type command struct { 
 id int 
 cmd string 
 args *json.rawmessage 
}

使用json.rawmessage的话,args字段在unmarshal时不会被解析,直接将字节数据赋值给args。我们可以能先解包第一层的json数据,然后根据cmd的值,再确定args的具体类型进行第二次unmarshal。

这里要注意的是,一定要使用指针类型*json.rawmessage,否则在args会被认为是[]byte类型,在打包时会被打包成base64编码的字符串。

使用interface{}

interface{}类型在unmarshal时,会自动将json转换为对应的数据类型:

json的boolean 转换为bool
json的数值 转换为float64
json的字符串 转换为string
json的array 转换为[]interface{}
json的object 转换为map[string]interface{}

json的null 转换为nil

需要注意的有两个。一个是所有的json数值自动转换为float64类型,使用时需要再手动转换为需要的int,int64等类型。第二个是json的object自动转换为map[string]interface{}类型,访问时直接用json object的字段名作为key进行访问。再不知道json数据的格式时,可以使用interface{}。

自定义类型

如果希望自己定义对象的打包解包方式,可以实现以下的接口:

type marshaler interface { 
 marshaljson() ([]byte, error) 
} 
type unmarshaler interface { 
 unmarshaljson([]byte) error 
} 

实现该接口的对象需要将自己的数据打包和解包。如果实现了该接口,json在打包解包时则会调用自定义的方法,不再对该对象进行其他处理。

总结

以上所述是小编给大家介绍的在go语言中使用json的方法,希望对大家有所帮助