猿问

从通用且以某种方式动态的 go 地图获取内容的最佳方式是什么?

我有这个 json 可以转换为:


var leerCHAT []interface{}

但是我正在经历疯狂的箍来到达地图内部和地图内部疯狂的地图上的任何点,特别是因为有些结果是不同的内容。这是Json


[

   null,

   null,

   "hub:zWXroom",

   "presence_diff",

   {

      "joins":{

         "f718a187-6e96-4d62-9c2d-67aedea00000":{

            "metas":[

               {

                  "context":{},

                  "permissions":{},

                  "phx_ref":"zNDwmfsome=",

                  "phx_ref_prev":"zDMbRTmsome=",

                  "presence":"lobby",

                  "profile":{},

                  "roles":{}

               }

            ]

         }

      },

      "leaves":{}

   }

]

我需要进入配置文件,然后里面有一个“DisplayName”字段。


所以我一直在做疯狂的黑客攻击..即使这样我也被卡住了一半......


首先是一个数组,所以我可以做一些事情[elementnumber] 然后是当棘手的映射开始时......对所有打印等感到抱歉,是为了调试并查看我要返回的元素数量。


if leerCHAT[3] == "presence_diff" {

                var id string

                presence := leerCHAT[4].(map[string]interface{})

                log.Printf("algo: %v", len(presence))

                log.Printf("algo: %s", presence["joins"])

                vamos := presence["joins"].(map[string]interface{})

                for i := range vamos {

                    log.Println(i)

                    id = i

                }

                log.Println(len(vamos))


                vamonos := vamos[id].(map[string]interface{})

                log.Println(vamonos)

                log.Println(len(vamonos))


                metas := vamonos["profile"].(map[string]interface{})   \\\ I get error here..


                log.Println(len(metas))

            }

到目前为止,我可以一直看到 meta:{...} 但无法继续将我的 hacky 代码用于我需要的内容。


注意:因为在 Joins: 和 metas: 之前的 id 是动态的,所以我必须以某种方式获取它,因为它始终只是一个元素,我做了 for range 循环来抓取它。


斯蒂芬大帝
浏览 116回答 1
1回答

弑天下

索引 3 处的数组元素描述了索引 4 处的变体 JSON 的类型。以下是如何将 JSON 解码为 Go 值。首先,为 JSON 的每个变体部分声明 Go 类型:type PrescenceDiff struct {     Joins map[string]*Presence // declaration of Presence type to be supplied     Leaves map[string]*Presence}type Message struct {     Body string}声明一个将类型字符串与 Go 类型相关联的映射:var messageTypes = map[string]reflect.Type{    "presence_diff": reflect.TypeOf(&PresenceDiff{}),    "message":       reflect.TypeOf(&Message{}),    // add more types here as needed}将变体部分解码为原始消息。使用索引 3 处的元素中的名称来创建适当 Go 类型的值并解码为该值:func decode(data []byte) (interface{}, error) {    var messageType string    var raw json.RawMessage    v := []interface{}{nil, nil, nil, &messageType, &raw}    err := json.Unmarshal(data, &v)    if err != nil {        return nil, err    }    if len(raw) == 0 {        return nil, errors.New("no message")    }    t := messageTypes[messageType]    if t == nil {        return nil, fmt.Errorf("unknown message type: %q", messageType)    }    result := reflect.New(t.Elem()).Interface()    err = json.Unmarshal(raw, result)    return result, err}使用类型开关访问消息的变体部分:defer ws.Close()for {    _, data, err := ws.ReadMessage()    if err != nil {        log.Printf("Read error: %v", err)        break    }    v, err := decode(data)    if err != nil {        log.Printf("Decode error: %v", err)        continue    }    switch v := v.(type) {    case *PresenceDiff:        fmt.Println(v.Joins, v.Leaves)    case *Message:        fmt.Println(v.Body)    default:        fmt.Printf("type %T not handled\n", v)    }}
随时随地看视频慕课网APP

相关分类

Go
我要回答