Maison >développement back-end >Golang >Comment désorganiser JSON dans des champs à l'aide d'une interface commune

Comment désorganiser JSON dans des champs à l'aide d'une interface commune

PHPz
PHPzavant
2024-02-09 16:51:18354parcourir

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

L'éditeur php Xinyi vous présente comment utiliser une interface commune pour désorganiser JSON dans des champs. En développement, nous devons souvent analyser les données JSON reçues en champs afin que les données puissent être facilement manipulées et traitées. Les interfaces génériques offrent un moyen simple et flexible d'atteindre cet objectif. En utilisant l'interface commune, nous pouvons transmettre une chaîne contenant des données JSON à la méthode de démarchage et obtenir les champs analysés pour un traitement ultérieur. Cette méthode est non seulement simple et facile à utiliser, mais convient également à différents types d'analyse de données JSON. Apprenons à décomposer JSON en champs à l'aide d'une interface commune !

Contenu de la question

J'ai un objet de réponse générique avec la structure suivante :

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

Solution de contournement

Vous devez indiquer encoding/json vers quel type spécifique démarcher. Ce package ne peut pas faire cela à votre place.

Supposons que typeatypeb soit défini comme :

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

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

Dans ce cas, il est impossible de décider vers quel type démarcher.

Concernant votre exemple, nous pouvons indiquer encoding/json le type à désorganiser comme suit :

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

Si vous ne connaissez pas le type à l'avance, vous pouvez le rassembler vers 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"`
 }

Et déterminez le type comme suit :

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

Une autre solution consiste à intégrer les informations de type dans 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"`
 }

Ensuite, décodez response.data en fonction de la valeur de response.type. Voir l'exemple fourni par response.type的值解码response.data。请参阅 encoding/json : https://pkg.go.dev/encoding/json#example-rawmessage-unmarshal.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer