Pourquoi ne json.Unmarshal travailler avec référence mais pas de pointeur?
Cet exemple de la json.Unmarshal docs (légèrement modifié pour des raisons de simplicité d'utilisation Animal
au lieu de []Animal
) fonctionne, pas d'erreurs:
Aire de jeux lien de travail exemple
//...
var animals Animal
err := json.Unmarshal(jsonBlob, &animals)
//...
Mais c'légèrement modifiée, par exemple ne le fait pas:
Aire de jeux lien de non-travail exemple
//...
var animals *Animal
err := json.Unmarshal(jsonBlob, animals)
//...
Il affiche cet obscur erreur qui n'est pas vraiment utile (ressemble plus à un appel de fonction que d'une erreur de l'OMI):
json: Unmarshal(néant *principaux.Animal)
Cela semble être parce que animals
est un pointeur non initialisé. Mais les docs disent (l'emphase est mienne):
Unmarshal unmarshals le JSON dans la valeur pointée par le pointeur. Si le pointeur est nul, Unmarshal attribue une nouvelle valeur pour le point de.
Alors pourquoi ne désordonnancement échouer dans le deuxième exemple et de montrer que les obscurs erreur?
(Aussi, est-il "unmarshalling" ou "désordonnancement" (un seul L)? Les docs d'utiliser les deux.)
- Sur la question de l'orthographe, l'anglais Britannique utilise le double " l " pour muselé et de l'ordonnancement (en.oxforddictionaries.com/definition/marshal), mais l'anglais Américain n'en a pas.
Vous devez vous connecter pour publier un commentaire.
Que vous avez rencontré un InvalidUnmarshalError (voir lignes 109 et 110 dans les décoder.aller).
Il semble que les docs pourrait faire avec quelques précisions comme la citation ci-dessus, ainsi que le commentaire ci-dessous à partir de la
Unmarshal
source semblent contredire les uns les autres.Parce que votre pointeur est nul.
Si vous initialisez cela fonctionne: http://play.golang.org/p/zprmV0O1fG
Aussi, il peut être orthographié de toute façon (la cohérence dans un seul doc serait bien, tout de même): http://en.wikipedia.org/wiki/Marshalling_(computer_science)
Je crois que le problème est que, si vous pouvez passer un pointeur à zéro à Unmarshal(), vous ne pouvez pas passer un néant la valeur du pointeur.
Un pointeur nul serait comme:
La valeur de
v
est nul, mais le pointeur dev
est non nulle d'une adresse de pointeur. C'est un non-zéro pointeur qui pointe vers un néant interface{} (qui est un type de pointeur). Unmarshal ne retourne pas une erreur dans ce cas.Un pointeur nul serait comme:
Dans ce cas, le type de v est
pointer to an interface{}
, mais comme avec toute déclaration de var dans golang, la valeur initiale dev
est le type de la valeur zéro. Doncv
est à zéro la valeur du pointeur, ce qui signifie qu'elle n'est pas de pointage pour être valable, toute la place en mémoire.Comme mentionné dans le https://stackoverflow.com/a/20478917/387176, json.Unmarshal() a besoin d'un pointeur valide pour quelque chose, de sorte qu'il peut changer quelque chose (que ce soit une valeur de zéro struct, ou un pointeur) à la place.
J'ai eu une semblable condition avant, mais dans un cas différent.
Il est en lien avec la notion d'interface en Aller.
Si une fonction déclare une interface comme argument ou la valeur de retour, l'appelant à passer ou le retour de la référence
Dans votre cas,
json.Unmarshal
accepter interface comme deuxième argument