首頁  >  文章  >  後端開發  >  如何使用通用介面將 JSON 解組為字段

如何使用通用介面將 JSON 解組為字段

PHPz
PHPz轉載
2024-02-09 16:51:18340瀏覽

如何使用通用接口将 JSON 解组为字段

php小編新一為您介紹如何使用通用介面將 JSON 解組為欄位。在開發中,我們經常需要將接收到的 JSON 資料解析為字段,以便能夠方便地操作和處理資料。通用介面提供了一種簡單而靈活的方式來實現這個目標。透過使用通用接口,我們可以將一個包含 JSON 資料的字串傳遞給解組方法,然後取得解析後的字段,以便後續的處理。這種方法不僅簡單易用,而且適用於各種類型的 JSON 資料解析。讓我們一起來學習如何使用通用介面將 JSON 解組為欄位吧!

問題內容

我有一個具有以下結構的通用回應物件:

type response struct {
    data          data   `json:"data"`
    error         string `json:"error,omitempty"`
    nextpagetoken string `json:"next_page_token,omitempty"`
}

data 類型是一個接口,有許多實作(例如 pingresponse 等)。如何將 response 解組為其基礎型別?完整的範例如下,它總是觸發錯誤 error: json: cannot unmarshal object into go struct field response.data of type main.data

type Response struct {
    Data          Data   `json:"data"`
    Error         string `json:"error,omitempty"`
    NextPageToken string `json:"next_page_token,omitempty"`
}

type Data interface{
    Foo()
}

type TypeA struct {
    Field1 string `json:"field1"`
    Field2 int    `json:"field2"`
}

func (a *TypeA) Foo() {}

type TypeB struct {
    Field3 float64 `json:"field3"`
}

func (b *TypeB) Foo() {}

func main() {
    jsonStr := `{
        "data": {
            "field1": "some string",
            "field2": 123
        },
        "error": "",
        "next_page_token": ""
    }`

    var response Response
    err := json.Unmarshal([]byte(jsonStr), &response)
    if err != nil {
        fmt.Println("error:", err)
        return
    }

    switch data := response.Data.(type) {
    case *TypeA:
        fmt.Println("TypeA:", data.Field1, data.Field2)
    case *TypeB:
        fmt.Println("TypeB:", data.Field3)
    default:
        fmt.Println("Unknown type")
    }
}

解決方法

您必須告訴 encoding/json 要解組到哪個具體型別。該軟體包無法為您完成此操作。

假設 typeatypeb 定義為:

type typea struct {
    fielda string `json:"field"`
}

type typeb struct {
    fieldb string `json:"field"`
}

在這種情況下,無法決定解組到哪種類型。

關於您的範例,我們可以告訴 encoding/json 要解群組的類型如下:

- var response response
+ response := response{data: &typea{}}

如果您事先不知道類型,可以將其編組到 map[string]interface{}:

type response struct {
-   data          data                   `json:"data"`
+   data          map[string]interface{} `json:"data"`
    error         string                 `json:"error,omitempty"` 
    nextpagetoken string                 `json:"next_page_token,omitempty"`
 }

並確定類型如下:

if field1, ok := response.data["field1"]; ok {
    fmt.println("typea:", field1, response.data["field2"])
} else {
    if field3, ok := response.data["field3"]; ok {
        fmt.println("typeb:", field3)
    } else {
        fmt.println("unknown type")
    }
}

另一種解決方案是在 json 中嵌入類型資訊:

jsonStr := `{
     "data": {
         "field1": "some string",
         "field2": 123
     },
+    type": "A",
     "error": "",
     "next_page_token": ""
 }`

 type Response struct {
-   Data          Data            `json:"data"`
+   Data          json.RawMessage `json:"data"`
+   Type          string          `json:"type"`
    Error         string          `json:"error,omitempty"`
    NextPageToken string          `json:"next_page_token,omitempty"`
 }

然後根據response.type的值解碼response.data。請參閱 encoding/json 提供的範例: https://pkg.go.dev/編碼/json#example-rawmessage-unmarshal

以上是如何使用通用介面將 JSON 解組為字段的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除