Heim >Backend-Entwicklung >Golang >So entpacken Sie JSON mithilfe einer gemeinsamen Schnittstelle in Felder

So entpacken Sie JSON mithilfe einer gemeinsamen Schnittstelle in Felder

PHPz
PHPznach vorne
2024-02-09 16:51:18347Durchsuche

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

php-Editor Xinyi stellt Ihnen vor, wie Sie eine gemeinsame Schnittstelle verwenden, um JSON in Felder zu entpacken. In der Entwicklung müssen wir häufig die empfangenen JSON-Daten in Felder analysieren, damit die Daten leicht manipuliert und verarbeitet werden können. Generische Schnittstellen bieten eine einfache und flexible Möglichkeit, dieses Ziel zu erreichen. Mithilfe der gemeinsamen Schnittstelle können wir eine Zeichenfolge mit JSON-Daten an die Unmarshalling-Methode übergeben und die analysierten Felder für die anschließende Verarbeitung abrufen. Diese Methode ist nicht nur einfach und benutzerfreundlich, sondern eignet sich auch für verschiedene Arten der JSON-Datenanalyse. Erfahren Sie, wie Sie JSON über eine gemeinsame Schnittstelle in Felder entmarshalieren!

Frageninhalt

Ich habe ein generisches Antwortobjekt mit der folgenden Struktur:

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")
    }
}

Problemumgehung

Sie müssen angeben encoding/json, zu welchem ​​spezifischen Typ die Bereitstellung aufgehoben werden soll. Dieses Paket kann dies nicht für Sie tun.

Angenommen, typeatypeb ist definiert als:

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

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

In diesem Fall ist es unmöglich zu entscheiden, zu welchem ​​Typ die Bereitstellung aufgehoben werden soll.

In Bezug auf Ihr Beispiel können wir encoding/json den Typ zum Unmarshalieren wie folgt bestimmen:

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

Wenn Sie den Typ vorher nicht kennen, können Sie ihn an map[string]interface{}:

weiterleiten
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"`
 }

Und bestimmen Sie den Typ wie folgt:

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")
    }
}

Eine andere Lösung besteht darin, Typinformationen in JSON einzubetten:

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"`
 }

Dann dekodieren Sie response.data basierend auf dem Wert von response.type. Sehen Sie sich das Beispiel von response.type的值解码response.data。请参阅 encoding/json an: https://pkg.go.dev/encoding/json#example-rawmessage-unmarshal.

Das obige ist der detaillierte Inhalt vonSo entpacken Sie JSON mithilfe einer gemeinsamen Schnittstelle in Felder. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen