Decodificando JSON en Golang usando json.Unmarshal vs json.NewDecoder.Decodificar


Estoy desarrollando un cliente API donde necesito codificar una carga JSON a petición y decodificar un cuerpo JSON a partir de la respuesta.

He leído el código fuente de varias bibliotecas y por lo que he visto, tengo básicamente dos posibilidades para codificar y decodificar una cadena JSON.

Uso json.Unmarshal pasar la cadena de respuesta completa

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

O usando json.NewDecoder.Decode

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

En mi caso, cuando se trata de respuestas HTTP que implementa io.Reader, la segunda versión parece requerir menos código, pero ya que he visto ambos me pregunto si hay alguna preferencia si debo usar una solución en lugar de la otra.

Además, la respuesta aceptada de esta pregunta dice

Utilice json.Decoder en lugar de json.Unmarshal.

Pero no mencionó la razón. ¿Debo realmente evitar usar json.Unmarshal?

 126
Author: Community, 2014-01-18

2 answers

Realmente depende de lo que su entrada es. Si observa la implementación del método Decode de json.Decoder, almacena en búfer todo el valor JSON en la memoria antes de desmarcarlo en un valor Go. Por lo tanto, en la mayoría de los casos no será más eficiente en memoria (aunque esto podría cambiar fácilmente en una versión futura del lenguaje).

Así que una mejor regla de oro es esta:

  • Use json.Decoder si sus datos provienen de un flujo io.Reader, o si necesita decodificar varios valores de un flujo de datos.
  • Use json.Unmarshal si ya tiene los datos JSON en memoria.

Para el caso de leer desde una solicitud HTTP, elegiría json.Decoder ya que obviamente estás leyendo desde una secuencia.

 152
Author: James Henstridge,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-14 01:50:31

Debemos obtener [] byte de la tubería antes de decodificar, por lo que leer desde io es necesario cuando se trata de conexiones HTTP, por lo que creo que la función two es igual. Pero cuando los datos tienen guardar en memoria, o tenemos obtener el byte [], podemos usar Unmarshal directamente, es mejor.

El json.Decoder se usa al leer y escribir en conexiones HTTP, WebSockets o archivos.

El json.Unmarshal se utiliza cuando la entrada es []byte

 -5
Author: seaside,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-26 09:25:11