Maison >développement back-end >Golang >Pourquoi `json.Unmarshal` avec un paramètre `interface{}` sans pointeur produit-il des résultats inattendus dans Go ?

Pourquoi `json.Unmarshal` avec un paramètre `interface{}` sans pointeur produit-il des résultats inattendus dans Go ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-04 20:19:12267parcourir

Why Does `json.Unmarshal` with a Non-Pointer `interface{}` Parameter Produce Unexpected Results in Go?

Incompréhension du type Interface{} : dévoiler les complexités

Dans Go, le type interface{} offre à la fois flexibilité et complexité. Cependant, une mauvaise compréhension de sa nature peut entraîner des conséquences inattendues, comme le montre un exemple déroutant.

Lorsque vous essayez de transmettre un type non-pointeur en tant que paramètre d'interface{} à une fonction et d'utiliser json.Unmarshal avec lui, le résultat peut être surprenant. L'exemple ci-dessous démontre ce comportement :

package main

import (
    "encoding/json"
    "fmt"
)

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    fmt.Printf("%T\n", i)
    fmt.Printf("%T\n", &i)
    json.Unmarshal(j, &i)
    fmt.Printf("%T\n", i)
}

type Test struct {
    Foo string
}

func main() {
    test(Test{})
}

Sortie :

main.Test
*interface {}
map[string]interface {}

Dévoilement du mystère

La confusion vient de la nature de l'interface {}. Ce n'est pas simplement un conteneur sans type mais plutôt un wrapper pour une paire (valeur, type). L'interface stocke une référence à la valeur concrète et à son type.

json.Unmarshal prend une valeur interface{} comme entrée, nous pouvons donc lui transmettre directement i. Tenter de prendre son adresse (comme avec &i) est inutile.

Pointeurs et interfaces

Cependant, si i contient une valeur non-pointeur, json.Unmarshal fait face à un défi. Étant donné que le package ne peut pas être désorganisé en un non-pointeur, il crée une nouvelle valeur de type interface{}. Cela lui permet de choisir le type, qui est par défaut map[string]interface{}.

Le scénario correct

Pour un scénario de pointeur, passer &i comme argument fonctionne car json.Unmarshal déréférence le pointeur pour trouver la valeur interface{} contenant la valeur *Test. Le pointeur garantit que le démarshalage se produit dans le type correct.

Conclusion

Pour éviter ces confusions, évitez d'utiliser des pointeurs vers des interfaces. Au lieu de cela, "placez" les pointeurs dans les interfaces et transmettez-les directement. En comprenant l'interaction entre l'interface{} et les pointeurs, les développeurs peuvent éviter des résultats inattendus et exploiter efficacement le système de types de Go.

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:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn