handling - Descifrando JSON en Golang usando json.Unmarshal vs json.NewDecoder.Decode
json to interface golang (2)
Debemos obtener el [] byte de la tubería antes de decodificar, por lo que leer de io es necesario cuando se trata de conexiones HTTP, por lo que creo que las dos funciones son iguales. Pero cuando los datos tienen guardado en la memoria, o tenemos 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 usa cuando la entrada es [] byte
Estoy desarrollando un cliente API donde necesito codificar una carga útil JSON a petición y decodificar un cuerpo JSON 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.
Usa json.Unmarshal
pasando toda la cadena de respuesta
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 como he visto ambas, me pregunto si existe alguna preferencia sobre si debo usar una solución en lugar de la otra.
Además, la respuesta aceptada de esta pregunta dice
Utilice
json.Decoder
lugar dejson.Unmarshal
.
pero no mencionó la razón. ¿Debería realmente evitar el uso de json.Unmarshal
?
Realmente depende de lo que sea tu entrada. 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 desasignarlo en un valor Go. Por lo tanto, en la mayoría de los casos ya no será más eficiente desde el punto de vista de la memoria (aunque esto podría cambiar fácilmente en una versión futura del lenguaje).
Entonces, una mejor regla empírica es esta:
- Use
json.Decoder
si sus datos provienen de una secuencia deio.Reader
o si necesita decodificar múltiples valores de una secuencia de datos. - Use
json.Unmarshal
si ya tiene los datos JSON en la memoria.
Para el caso de leer de una solicitud HTTP, escogería json.Decoder
ya que obviamente está leyendo de una transmisión.