Json 如何使用FieldByName提取嵌套结构值
以下是结构:Json 如何使用FieldByName提取嵌套结构值,json,go,Json,Go,以下是结构: type UP struct { Rxinfo []struct { Gatewayid string `json:"gatewayID"` Uplinkid string `json:"uplinkID"` Name string `json:"name"` Time time.Time `json:"
type UP struct {
Rxinfo []struct {
Gatewayid string `json:"gatewayID"`
Uplinkid string `json:"uplinkID"`
Name string `json:"name"`
Time time.Time `json:"time"`
Rssi int `json:"rssi"`
Lorasnr float64 `json:"loRaSNR"`
Location struct {
Latitude int `json:"latitude"`
Longitude int `json:"longitude"`
Altitude int `json:"altitude"`
} `json:"location"`
} `json:"rxInfo"`
Adr bool `json:"adr"`
Fcnt int `json:"fCnt"`
Data string `json:"data"`
}
当我这样编码时:
{
"rx_info":[
{
"gateway_id":"1",
"up_link_id":"2",
"name":"sunstrider",
"time":"2021-05-25T19:37:00Z",
"rssi":-21,
"lo_ra_snr":0.342,
"location":{
"latitiude":413,
"longitude":124,
"altitude":41
}
},
{
"gateway_id":"2",
"up_link_id":"4",
"name":"sunstrider 2",
"time":"2021-06-25T19:37:00Z",
"rssi":-41,
"lo_ra_snr":0.562,
"location":{
"latitiude":213,
"longitude":321,
"altitude":443
}
}
],
"address":true,
"fcnt":53,
"data":"this is the data"
}
up:=up{}
如果错误:=json.Unmarshal(msg.Payload(),&up);呃!=零{
fmt.Printf(“无法分析消息(%s):%s”,msg.Payload(),错误)
}
val:=reflect.ValueOf(up).FieldByName(“名称”)
格式打印F(“%v”,val)
它返回
日志返回
错误的原因是字段名称
位于结构片内部。如果要从结构的切片中获取字段的值,必须指定要从哪个切片索引中获取值
例如,您的有效负载如下所示:
{
"rx_info":[
{
"gateway_id":"1",
"up_link_id":"2",
"name":"sunstrider",
"time":"2021-05-25T19:37:00Z",
"rssi":-21,
"lo_ra_snr":0.342,
"location":{
"latitiude":413,
"longitude":124,
"altitude":41
}
},
{
"gateway_id":"2",
"up_link_id":"4",
"name":"sunstrider 2",
"time":"2021-06-25T19:37:00Z",
"rssi":-41,
"lo_ra_snr":0.562,
"location":{
"latitiude":213,
"longitude":321,
"altitude":443
}
}
],
"address":true,
"fcnt":53,
"data":"this is the data"
}
请注意,字段Name
如何位于数组中的对象中。如果有效负载如下所示,则代码应如下所示:
{
"rx_info":[
{
"gateway_id":"1",
"up_link_id":"2",
"name":"sunstrider",
"time":"2021-05-25T19:37:00Z",
"rssi":-21,
"lo_ra_snr":0.342,
"location":{
"latitiude":413,
"longitude":124,
"altitude":41
}
},
{
"gateway_id":"2",
"up_link_id":"4",
"name":"sunstrider 2",
"time":"2021-06-25T19:37:00Z",
"rssi":-41,
"lo_ra_snr":0.562,
"location":{
"latitiude":213,
"longitude":321,
"altitude":443
}
}
],
"address":true,
"fcnt":53,
"data":"this is the data"
}
主程序包
进口(
“编码/json”
“fmt”
“反映”
“时间”
)
键入结构{
RxInfo[]RxInfo`json:“rx_信息”`
地址bool`json:“地址”`
FCNT int`json:“FCNT”`
数据字符串`json:“数据”`
}
类型RxInfo结构{
GatewayID字符串`json:“网关\u id”`
上行链路id字符串`json:“上行链路id”`
名称字符串`json:“名称”`
Time.Time`json:“Time”`
RSSI int`json:“RSSI”`
LORA64`json:“低信噪比”`
Location`json:“Location”`
}
类型位置结构{
纬度int`json:“纬度”`
经度int`json:“经度”`
高度int`json:“高度”`
}
func main(){
up:=up{}
如果err:=json.Unmarshal([]字节(有效负载),&up);err!=nil{
fmt.Printf(“无法分析消息(%s):%s)”,有效负载,错误)
}
//因为“Name”字段在数组中,所以我们必须
//将有效负载数组绑定到预定义结构的数组
valSlice:=reflect.ValueOf(up).FieldByName(“RxInfo”).Interface()([]RxInfo)
//从第0个索引中获取值
fmt.Println(valSlice[0].Name)
//从第一个索引中获取值
fmt.Println(valSlice[1].Name)
//因为您的目标是获取字段的值,所以我建议您
//使用结构的结构获取值,使用
//“点”运算符,而不是使用FieldByName()的函数
valString:=up.RxInfo[0]。名称
格式打印LN(valString)
}
此外,还有一些保持代码整洁的提示:
- 您应该始终使用结构的结构访问有效负载的值。只有当您不知道有效负载的完整结构时,才使用
reflect.ValueOf(variable).FieldByName(“name\u of\u field”)
- 如果您有一个深度嵌套的结构,请将它们拆分为多个微小的结构(如上面的示例),以使其更易于阅读和维护
- 标准化您的命名约定。这适用于命名变量、结构、结构字段、结构标记等。我个人对字段名使用camel-case,对json结构标记使用snake-case
Name
是切片中包含的结构中的字段。该结构可以有零个或多个值。你想要哪一个?对不起,先生,我不明白。我的难题是,当我提取像Adr这样未嵌套在struct中的数据时,它不会报告错误,但当我提取Name时,它会报告错误。所以我需要调整程序结构。我不太明白0或更多值的含义。您有一个带有Name
字段的结构片。一个切片可以有零个或多个元素。如果您不知道切片是什么,或者不知道为什么切片可以有零个或多个元素,请使用。