使用反射迭代 json
Iterating over json using reflection
我正在尝试使用我的 golang 项目中的休息端点。 JSON 结构非常大并且是半结构化的,所以我使用反射对其进行迭代并获取我感兴趣的信息。
这是我解组响应的方式:
var m map[string]interface{}
json.Unmarshal(bytes, &m)
但我卡住的部分是 - 我正在遍历一片地图(我认为)但我无法获取地图的键或值。这是有问题的代码。
if val, ok := m["messages"]; ok {
s := reflect.ValueOf(val)
if s.Kind() == reflect.Slice {
for i := 0; i < s.Len(); i++ {
item := s.Index(i)
fmt.Println("VALUE = ", item.Elem())
fmt.Println("KIND = ", item.Kind())
}
}
return
}
当我 运行 代码时,显示的值看起来像一张地图:
map[decoration_stats:<nil> highlight_ranges:map[] index:graylog_7 message:map[_id:49272694-1834-11ea-8928-0242ac120004 docker:{"container_id":"0f9d97722c25240c6f99487b247b2416177a749de47d661cd661334514e0e74f"} facility:fluentd gl2_message_id:01DVDSM9VSDQ5PF81T4C31NSH6....
种类是:
KIND = interface
我尝试了各种方法,例如:
for _, e := range val.MapKeys() {
v := val.MapIndex(e)
fmt.Println(v)
}
但是代码出现恐慌:
panic: reflect: call of reflect.Value.MapKeys on interface Value
抱歉,我对 golang 有点陌生,但在涉及任何反射类型编程时使用过其他静态类型语言,主要是 Java。
我的问题是如何将此接口转换为映射或某种具体类型以便我可以使用它。任何帮助将不胜感激。
使用反射是一种低效的方法。 JSON unmarshal,当与接口(和 map[string]interface{})一起使用时,会产生一组有限的类型,您可以使用类型断言或类型开关来处理它:
if val, ok := m["messages"]; ok {
switch v:=val.(type) {
case map[string]interface{}: // JSON object
for key, value:=range v {
}
case []interface{}: // JSON array
for i,node:=range v {
}
case string: // string value
case float64: // numeric value
case bool: // boolean value
case json.Number: // If you use json.Decoder with UseNumber()
}
}
我正在尝试使用我的 golang 项目中的休息端点。 JSON 结构非常大并且是半结构化的,所以我使用反射对其进行迭代并获取我感兴趣的信息。
这是我解组响应的方式:
var m map[string]interface{}
json.Unmarshal(bytes, &m)
但我卡住的部分是 - 我正在遍历一片地图(我认为)但我无法获取地图的键或值。这是有问题的代码。
if val, ok := m["messages"]; ok {
s := reflect.ValueOf(val)
if s.Kind() == reflect.Slice {
for i := 0; i < s.Len(); i++ {
item := s.Index(i)
fmt.Println("VALUE = ", item.Elem())
fmt.Println("KIND = ", item.Kind())
}
}
return
}
当我 运行 代码时,显示的值看起来像一张地图:
map[decoration_stats:<nil> highlight_ranges:map[] index:graylog_7 message:map[_id:49272694-1834-11ea-8928-0242ac120004 docker:{"container_id":"0f9d97722c25240c6f99487b247b2416177a749de47d661cd661334514e0e74f"} facility:fluentd gl2_message_id:01DVDSM9VSDQ5PF81T4C31NSH6....
种类是:
KIND = interface
我尝试了各种方法,例如:
for _, e := range val.MapKeys() {
v := val.MapIndex(e)
fmt.Println(v)
}
但是代码出现恐慌:
panic: reflect: call of reflect.Value.MapKeys on interface Value
抱歉,我对 golang 有点陌生,但在涉及任何反射类型编程时使用过其他静态类型语言,主要是 Java。
我的问题是如何将此接口转换为映射或某种具体类型以便我可以使用它。任何帮助将不胜感激。
使用反射是一种低效的方法。 JSON unmarshal,当与接口(和 map[string]interface{})一起使用时,会产生一组有限的类型,您可以使用类型断言或类型开关来处理它:
if val, ok := m["messages"]; ok {
switch v:=val.(type) {
case map[string]interface{}: // JSON object
for key, value:=range v {
}
case []interface{}: // JSON array
for i,node:=range v {
}
case string: // string value
case float64: // numeric value
case bool: // boolean value
case json.Number: // If you use json.Decoder with UseNumber()
}
}