go json的key为数字怎么解析_Golang处理json动态key的几种情况

附带一个 json 解析遇到的坑

经常会遇到 json 中的某个 key 是动态的情况, 比如下面这样:

1234567891011121314

{

"friends": [

{

"id": 0,

"name": "Robinson Woods"

}

],

"parent": [

{

"id": 1,

"name": "Alejandra Mcdaniel"

}

]

}

遇到这种, 只需要当成 map 类型来解析即可:

1234567891011121314151617181920212223242526272829303132

package main

import (

"encoding/json"

"log"

)

func main() {

data := `{"friends": [{"id": 0,"name": "Robinson Woods"}],"parent": [{"id": 1,"name": "Alejandra Mcdaniel"}]}`

type User struct {

ID int `json:"id"`

Name string `json:"name"`

}

dataMap := make(map[string][]User)

json.Unmarshal([]byte(data), &dataMap)

for k, v := range dataMap {

log.Printf(`%v,%v`, k, v)

}

}

而如果 json 返回格式不固定的时候, 这时就应该使用json.RawMessage 类型了, 官方解释如下

RawMessage is a raw encoded JSON value. It implements Marshaler and Unmarshaler and can be used to delay JSON decoding or precompute a JSON encoding.

大致意思就是暂时不解析这部分, 之后这部分可以进行二次解析, 最适合那种返回的内容格式不固定的情况. 之后的处理, 如果知道固定的几种格式可以通过断言来判断返回的是哪种, 不然的话就只能断言成 interface 类型然后一层层解析了.

而更复杂一点的情况, 动态 key 后面可能是一个没有 key 的数组, 这种目前 go 不支持, 只能通过类型断言来解决了

断言注意事项

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

1234567891011

JSON的boolean 转换为bool

JSON的数值 转换为float64

JSON的字符串 转换为string

JSON的Array 转换为[]interface{}

JSON的Object 转换为map[string]interface{}

JSON的null 转换为nil

所以如果你已经把 json 解析过一次了,是不可能再断言成 struct 类型的, struct统统变成了 map 类型, 这时有俩办法, 在解析时就用对应的 struct 类型,而不是写成 interface, 第二种就是把 map 再 Marshal 成 byte数组 类型, 然后再Unmarshal回 struct, 不用脑子想就知道不要用第二种…..

踩坑

json解析tag不区分大小写

遇到过各种奇奇怪怪的 json ,在解析下面这种, key 仅仅大小写不一样的时候就要注意了, 如果你平时写 struct 喜欢简洁, 就是用不到的字段不写的话, 这时可能就有问题了, 因为 标准库的json在解析 tag 时,是不区分大小写的, 会出现如下图的覆盖情况

忽略 json 字段别写错 tag

json:"omitempty" tag 的意思是如果该值为该类型的零值时会忽略,

想完全忽略某个 json 字段返回,应该使用json:"-"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值