问题描述
对于这个基本问题,我深表歉意。我是 Golang 的新手,我有要解析的 json 如下
{
"config1":{
"Parameters":{
"Pm1":"value","Pm2":"value","Pm3":"value"
},"dynamic_key1":{
"Parameters":{
"a":"value","b":"value","c":"value","d":"value"
},"Epoch":"value"
},"Epoch":"value"
}
}
我正在尝试编写一个结构来解析这个 json 并按以下方式编写该结构。
type Parameters struct {
Pm1 string `json:"Pm1"`
Pm2 string `json:"Pm2"`
Pm3 string `json:"Pm3"`
}
type dynamicParametes struct {
a string `json:"a"`
b string `json:"b"`
c string `json:"c"`
d string `json:"d"`
}
type dynamic struct {
Parameters dynamicParametes `json:"Parameters"`
Epoch string `json:"Epoch"`
}
type config1 struct {
Parameters Parameters `json:"Parameters"`
Dynamic_keys map[string]dynamic `json:"-"`
Epoch string `json:"Epoch"`
}
type config struct {
config1 config1 `json:"config1"`
}
我希望地图将所有匹配的键与动态结构相匹配,并将它们显示在地图中。但是,我看到它在响应中创建了一个空地图。
解决方法
为配置类型实现了自定义解压缩器。
注意
-
如果您不需要
Parameters
和dynamicParametes
作为结构类型,您可以简单地将它们解组为map[string]string
-
您必须公开结构中的所有字段才能进行 json 解组
-
验证您的 json 字符串
type config struct {
Config1 config1 `json:"config1"`
}
type _config config
func (b *config) UnmarshalJSON(data []byte) error {
var v = struct {
Config1 map[string]interface{} `json:"config1"`
}{}
if err := json.Unmarshal(data,&v); err != nil {
return err
}
c := _config{}
err := json.Unmarshal(data,&c)
if err != nil {
return err
}
b.Config1.Parameters = c.Config1.Parameters
b.Config1.Epoch = c.Config1.Epoch
if b.Config1.Dynamic_keys == nil {
b.Config1.Dynamic_keys = map[string]dynamic{}
}
for key,config := range v.Config1 {
if key == `Parameters` || key == `Epoch` {
continue
}
data,err := json.Marshal(config)
if err != nil {
return err
}
d := dynamic{}
err = json.Unmarshal(data,&d)
if err != nil {
return err
}
b.Config1.Dynamic_keys[key] = d
}
return nil
}
你可以看到完整的代码here
,您所需要的只是了解基本数据类型在 json 中的外观。
json 中的字段 microbenchmark::microbenchmark(f_dc(),f_akrun1(),f_akrun2(),f_akrun3(),f_forloop(),times = 5)
Unit: milliseconds
expr min lq mean median uq max neval cld
f_dc() 6453.14052 6512.34196 6772.0079 6534.08171 6939.61358 7420.86152 5 d
f_akrun1() 1288.96812 1328.96075 1377.0833 1353.79346 1372.30852 1541.38573 5 b
f_akrun2() 3685.33619 3703.33018 3814.8367 3801.52657 3915.75432 3968.23609 5 c
f_akrun3() 178.30997 179.77604 194.0712 189.18425 205.37485 217.71095 5 a
f_forloop() 30.11329 33.37171 35.0534 36.80903 36.95909 38.01389 5 a
很简单 Parameters
,您可以使用标准的 json.Unmasrhall 对其进行解组,而无需额外实现接口 map[string]string
。
Link for Go Playground with code below
json.Unmarshaler
输出:
package main
import (
"encoding/json"
"fmt"
)
const jsonStr = `{
"config1":{
"Parameters":{
"Pm1":"value_1","Pm2":"value_2","Pm3":"value_3"
},"dynamic_key1":{
"Parameters":{
"a":"value_1","b":"value_2","c":"value_3","d":"value_4"
},"Epoch":"value"
},"Epoch":"value"
}
}`
type Data struct {
Config1 struct {
Parameters map[string]string `json:"Parameters"`
Dynamic struct {
Parameters map[string]string `json:"Parameters"`
Epoch string `json:"Epoch"`
} `json:"dynamic_key1"`
Epoch string `json:"Epoch"`
} `json:"config1"`
}
func main() {
var data Data
_ = json.Unmarshal([]byte(jsonStr),&data)
fmt.Printf("%+v\n",data)
}