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 dejson.Unmarshal
.
Pero no mencionó la razón. ¿Debo realmente evitar usar json.Unmarshal
?
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 flujoio.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.
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
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