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
字段的结构片。一个切片可以有零个或多个元素。如果您不知道切片是什么,或者不知道为什么切片可以有零个或多个元素,请使用。