Décoder JSON à Golang en utilisant json.Unmarshal contre json.NewDecoder.Décoder

je développe un client API où je dois encoder une charge JSON sur demande et décoder un corps JSON de la réponse.

j'ai lu le code source de plusieurs bibliothèques et d'après ce que j'ai vu, j'ai essentiellement deux possibilités pour encoder et décoder une chaîne JSON.

utiliser json.Unmarshal passer toute la chaîne de réponse

data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
    err = json.Unmarshal(data, value)
}

ou en utilisant json.NewDecoder.Decode

err = json.NewDecoder(resp.Body).Decode(value)

dans mon cas, lorsqu'il s'agit de réponses HTTP qui implémentent io.Reader , la seconde version semble nécessiter moins de code, mais comme j'ai vu les deux, je me demande s'il y a une préférence pour que j'utilise une solution plutôt que l'autre.

de plus, la réponse acceptée de cette question dit

veuillez utiliser json.Decoder au lieu de json.Unmarshal .

mais il n'a pas mentionné la raison. Dois-je vraiment éviter d'utiliser json.Unmarshal ?

126
demandé sur Community 2014-01-18 02:34:55

2 réponses

Cela dépend vraiment de ce que votre entrée est. Si vous regardez l'implémentation de la méthode Decode de json.Decoder , elle tamponne toute la valeur JSON en mémoire avant de la démonter dans une valeur Go. Ainsi, dans la plupart des cas, il ne sera pas plus efficace de mémoire (bien que cela pourrait facilement changer dans une version future de la langue).

voici donc une meilleure règle empirique:

  • utilisez json.Decoder si vos données proviennent de un flux io.Reader , ou vous devez décoder plusieurs valeurs à partir d'un flux de données.
  • utilisez json.Unmarshal si vous avez déjà les données JSON en mémoire.

pour le cas d'une lecture à partir D'une requête HTTP, je choisirais json.Decoder puisque vous êtes évidemment en train de lire à partir d'un flux.

152
répondu James Henstridge 2016-07-14 01:50:31

nous devons obtenir []byte à partir de la pipe avant de décoder, donc lire à partir de io est nécessaire lorsque traiter avec des connexions HTTP, donc je pense que les deux fonctions sont égales. Mais lorsque les données ont enregistrer en mémoire, ou nous avons obtenir le byte [], nous pouvons utiliser Unmarshal directement, il est préférable.

le json.Decoder est utilisé lors de la lecture et de l'écriture de connexions HTTP, WebSockets, ou des fichiers.

Le json.Unmarshal est utilisé lorsque l'entrée est []byte

-5
répondu seaside 2015-11-26 09:25:11