为了账号安全,请及时绑定邮箱和手机立即绑定

无法将 []interface{} 转换为 []byte:“interface {}

无法将 []interface{} 转换为 []byte:“interface {}

Go
潇湘沐 2022-06-27 15:26:37
我正在解析大型 JSON 文件,我需要解析它的子对象items。您可以看到它items的类型[]interface{}:我成功解析了第一个对象map[]string]interface{},但之后我尝试解析pods["items"]类型中的哪个对象,[]interface{}然后我将它转换[]byte为json.Unmarshal函数,但它失败了:interface {} 是 []interface [],而不是 []uint8这是重现的代码:package mainimport (    "encoding/json"    "fmt")var mytest string = `{   "kind":"PodList",   "apiVersion":"v1",   "metadata":{        },   "items":[{         "metadata":{            "name":"super-user-pod5551",            "namespace":"kube-system",            "selfLink":"/api/v1/namespaces/kube-system/pods/super-user-pod5551",            "uid":"fe9cf599-6e82-4a1b-8db5-5e319a58e1da"         },         "spec":{            "volumes":[               {                  "name":"bootstrap-signer-token-dmp5q",                  "secret":{                     "secretName":"bootstrap-signer-token-dmp5q",                     "defaultMode":420                  }               }            ],            "containers":[               {                  "name":"redis",                  "image":"busybox:1.28",                  "resources":{                                       },                  "volumeMounts":[                     {                        "name":"bootstrap-signer-token-dmp5q",                        "readOnly":true,                        "mountPath":"/var/run/secrets/kubernetes.io/serviceaccount"                     }                  ],                  "terminationMessagePath":"/dev/termination-log",                  "terminationMessagePolicy":"File",                  "imagePullPolicy":"IfNotPresent",                  "securityContext":{                     "capabilities":{                        "add":[                           "SYS_TIME"                        ]                     }                  }               }            ],            "restartPolicy":"Always",            "terminationGracePeriodSeconds":30,            "schedulerName":"default-scheduler"         },         }      }    ]}`链接到 GoPlayground。
查看完整描述

2 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

问题是您没有像您声称的那样进行类型转换。相反,您正在执行类型断言。

由于pods["items"]是 a []interface{},因此您首先需要每个接口具有具体类型,[]byte并对每个接口进行断言,然后将它们收集到 a[]byte中,然后才能执行解组。

最终你应该创建一个struct你可以简单地解组的,这将大大简化你的代码。

正如其他人所说,您进行两次解组的事实应该表明有更好的方法。


查看完整回答
反对 回复 2022-06-27
?
当年话下

TA贡献1890条经验 获得超9个赞

在我阅读了这篇博客中的“任意对象和数组”之后,我明白了如何去做。


就像@Steven Eckhoff 提到的那样,我需要将map[string]interface{}对象移动到一个变量中,然后用键和值对其进行运行,我可以按其类型检查每个值并遍历这些对象。


以下是解决方案的主要代码示例:


func main(){


    var pods interface{}

    //var pods PodList

    err := json.Unmarshal([]byte(mytest), &pods)


    if err != nil {

        log.Fatal(err)

    }

    data := pods.(map[string]interface{})

    for k, v := range data {

        switch v := v.(type) {

        case string:

            fmt.Println(k, v, "(string)")

        case float64:

            fmt.Println(k, v, "(float64)")

        case []interface{}:

            fmt.Println(k, "(array):")

            for _, u := range v {

                //fmt.Println("    ", i, u)

                u := u.(map[string]interface{})

                for a,b := range u {

                    if a == "metadata" {

                        b := b.(map[string]interface{})

                        for c,e := range b {

                            if c == "name" {

                                fmt.Println(e)

                            }

                        }

                    }

                    //fmt.Println("    ", a, b)

                }

            }

        default:

            fmt.Println(k, v, "(unknown)")

        }

    }

}

输出:


kind PodList (string)

apiVersion v1 (string)

metadata map[] (unknown)

items (array):

super-user-pod5551

最好的方法是struct为对象定义,但我有兴趣了解如何在没有struct.


查看完整回答
反对 回复 2022-06-27
  • 2 回答
  • 0 关注
  • 707 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号