-1

我正在尝试在我的 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。

我的问题是如何将此接口转换为地图或某种具体类型,以便我可以使用它。任何帮助将不胜感激。

4

1 回答 1

2

使用反射是一种低效的方法。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()
   }
}
于 2019-12-06T14:44:56.267 回答