Estoy desarrollando un cliente API donde necesito codificar una carga JSON a pedido 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.
Use json.Unmarshalpasar 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 se implementan io.Reader, la segunda versión parece requerir menos código, pero como he visto ambas, me pregunto si hay alguna preferencia si debería usar una solución en lugar de la otra.
Además, la respuesta aceptada de esta pregunta dice
Por favor, use en
json.Decoderlugar dejson.Unmarshal.
pero no mencionó la razón. ¿Debo realmente evitar usar json.Unmarshal?

ioutil.ReadAlles algo incorrecto. No está relacionado con su objetivo, pero requiere que tenga suficiente memoria contigua para almacenar lo que pueda venir, incluso si los últimos 20 TB de respuesta son posteriores al último en su JSON.}io.LimitReaderpara evitar eso.Respuestas:
Realmente depende de cuál sea su aporte. Si observa la implementación del
Decodemétodo dejson.Decoder, almacena el valor JSON completo en la memoria antes de descomponerlo en un valor Go. Por lo tanto, en la mayoría de los casos no será más eficiente en la memoria (aunque esto podría cambiar fácilmente en una versión futura del idioma).Así que una mejor regla general es esta:
json.Decodersi sus datos provienen de unaio.Readersecuencia, o si necesita decodificar múltiples valores de una secuencia de datos.json.Unmarshalsi ya tiene los datos JSON en la memoria.Para el caso de leer desde una solicitud HTTP, elegiría
json.Decoderya que obviamente está leyendo desde una secuencia.fuente
Bufferedmétodo está ahí para permitirle ver los datos adicionales que se leyeron en el búfer interno después del valor.