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
Freigeben: 2024-02-09 16:51:18
nach vorne
481 Leute haben es durchsucht

如何使用通用接口将 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"`
}

Nach dem Login kopieren

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")
    }
}
Nach dem Login kopieren

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"`
}
Nach dem Login kopieren

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{}}
Nach dem Login kopieren

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"`
 }
Nach dem Login kopieren

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")
    }
}
Nach dem Login kopieren

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"`
 }
Nach dem Login kopieren

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!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage