簡體   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