繁体   English   中英

golang json 和接口切片

[英]golang json and slices of interface

我在迭代包含接口切片的接口切片时遇到问题。

此问题是通过尝试使用返回 JSON 数据的 API 调用而出现的。 返回了相当多的数据,并且结构因请求而异。 API 文档中也没有 JSON 响应的结构,因此我尝试实现一些方法来处理任意 JSON 响应。

目前,当初始调用被放入 map[string]interface{} 中,然后运行 ​​switch 语句以确定每个元素的类型时,当遇到接口切片时就会出现问题。 我似乎不能对他们做任何事情。

我曾多次尝试使用 sort 包(特别是 sort 和 slicestable 函数),但无济于事。

我收到的错误是:

interface conversion: interface {} is []interface {}, not map[string]interface {}

当我尝试映射接口切片时会发生这种情况,以便我可以再次使用 switch 语句迭代它们。

output := make(map[string]interface{})
err = json.Unmarshal(body, &output)

fmt.Println(err)
identify(output)

return err
}

func identify(output map[string]interface{}) {
    fmt.Printf("%T", output)
    for a, b := range output {
        switch bb := b.(type) {
        case string:
            fmt.Println("This is a string")
        case float64:
            fmt.Println("this is a float")
        case []interface{}:
            fmt.Println(" is []interface ", bb)
            test := b.(map[string]interface{}) // falis here
            fmt.Println("Success!", test)
        default:
            return
        }
    }
}

所以基本问题是如何在不知道结构的情况下迭代嵌套的接口切片?

好吧,您不能将[]interface{}map[string]interface{} 因为它是一个切片,你可以遍历其元素(注意, bbb已转换为相应的类型,你不必投b再次):

    case []interface{}:
        fmt.Println(" is []interface ", bb)
        for _, val := range bb {
            // do something with val
        }
    default:
    ...

为什么你必须处理你不知道的事情? 您是否有可能重新考虑您的架构并使用已知类型? 你见过 使用json.RawMessage延迟解组例子吗? 或者尝试实现 Unmarshaler 接口

您可以添加一个 switch case,它检查接口切片的接口类型,然后运行与递归相同的函数,直到解析整个 json。

output := make(map[string]interface{})
err = json.Unmarshal(body, &output)

fmt.Println(err)
identify(output)

return err
}

func identify(output map[string]interface{}) {
    fmt.Printf("%T", output)
    for a, b := range output {
        switch bb := b.(type) {
        case string:
            fmt.Println("This is a string")
        case float64:
            fmt.Println("this is a float")
        case []interface{}:
        // Access the values in the JSON object and place them in an Item
        for _, itemValue := range jsonObj {
            fmt.Printf("%v is an interface\n", itemValue)
            identify(itemValue.(map[string]interface{}))
        }
        default:
            return
        }
    }
}

可以有深层嵌套的 json。 我们只需要为每种情况创建选项,直到 json 被完全解析。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM