gpt4 book ai didi

json - 从 JSON 中的 JSON 数组中提取值(以及为什么不反射(reflect)和编译错误报告相同的类型)

转载 作者:数据小太阳 更新时间:2023-10-29 03:23:25 24 4
gpt4 key购买 nike

我在用 Go 解码一些 JSON 时遇到问题。在下面的代码中,我希望能够从 JSON(<- 主要目标/问题)中提取“c”(“Apple”、“Berry”)的值。让我特别困惑的是,当我试图索引到 v 数组(?)时,我得到错误:invalid operation: v[0] (type interface {} does not support indexing )

这就是让我使用 reflect 并查看变量类型的原因,如下所示,它是“[]interface {}”,即使我断言它是“界面 {}”。值得注意的是,如果我将行 q := interface{}(v) 变成 q := []interface{}(v),我得到:无法将 v(类型接口(interface) {})转换为类型 []接口(interface) {}:需要类型断言。我错过了什么?为什么 reflect 说它是“[]interface {}”但错误说它是“interface {}”? (<- 次要问题/帮助我理解)

package main

import (
"encoding/json"
"fmt"
"reflect"
)

func main() {
data := []byte("{ \"a\" : { \"b\" : [ { \"n\" : 100, \"c\" : \"Apple\", \"m\" : 1, \"bool\" : false }, { \"n\" : 101, \"c\" : \"Berry\", \"m\" : 2, \"bool\" : false } ] }, \"foo\" : false, \"bar\" : \"foobar\" }")
var a map[string]interface{}

_ = json.Unmarshal(data, &a)

b := a["a"].(map[string]interface{})
for i, v := range b {
fmt.Println(i, reflect.TypeOf(v))
q := interface{}(v)
fmt.Println(q, reflect.TypeOf(q))
}

}

输出:

b []interface {}
[map[m:1 bool:false n:100 c:Apple] map[c:Berry m:2 bool:false n:101]] []interface {}

最佳答案

您可以创建特定类型来为数据建模,而不是尝试将 json 解码到接口(interface)中。请参阅下面的示例代码。

package main

import (
"encoding/json"
"fmt"
)

func main() {
data := []byte("{ \"a\" : { \"b\" : [ { \"n\" : 100, \"c\" : \"Apple\", \"m\" : 1, \"bool\" : false }, { \"n\" : 101, \"c\" : \"Berry\", \"m\" : 2, \"bool\" : false } ] }, \"foo\" : false, \"bar\" : \"foobar\" }")

type c struct {
N int `json:"n"`
C string `json:"c"`
M int `json:"m"`
B bool `json:"bool"`
}
type b struct {
C []c `json:"b"`
Foo bool `json:"foo"`
Bar string `json:"bar"`
}
type a struct {
A b `json:"a"`
}


var result a
if err := json.Unmarshal(data, &result); err != nil {
panic(err.Error())
}

fmt.Printf("%+v", result)
}

Link to playground .

输出:{A:{C:[{N:100 C:Apple M:1 B:false} {N:101 C:Berry M:2 B:false}] Foo:false Bar:} }

请注意,类型成员是大写的 - 这是 json 解码正常工作所必需的。

一旦 json 被解码到您的类型中,您就可以按照您的期望引用成员:

    for _, v := range result.A.C {
fmt.Println(v)
}

输出:

{100 Apple 1 false}
{101 Berry 2 false}

关于json - 从 JSON 中的 JSON 数组中提取值(以及为什么不反射(reflect)和编译错误报告相同的类型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48997822/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com