Я разрабатываю клиент API, в котором мне нужно кодировать полезную нагрузку JSON по запросу и декодировать тело JSON из ответа.
Я прочитал исходный код из нескольких библиотек и из того, что я видел, у меня есть две возможности кодирования и декодирования строки JSON.
Использовать json.Unmarshal
передачу всей строки ответа
data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
err = json.Unmarshal(data, value)
}
или используя json.NewDecoder.Decode
err = json.NewDecoder(resp.Body).Decode(value)
В моем случае, когда речь идет о HTTP-ответах, которые реализуются io.Reader
, вторая версия, похоже, требует меньше кода, но, поскольку я видел оба, я задаюсь вопросом, есть ли какое-либо предпочтение, следует ли мне использовать решение, а не другое.
Более того, принятый ответ на этот вопрос говорит
Пожалуйста, используйте
json.Decoder
вместоjson.Unmarshal
.
но это не упомянуло причину. Должен ли я действительно избегать использования json.Unmarshal
?
ioutil.ReadAll
это почти всегда неправильно , что нужно делать. Это не связано с вашей целью, но требует, чтобы у вас было достаточно непрерывной памяти для хранения всего, что может идти по трубе, даже если последние 20 ТБ ответа идут после последних}
в вашем JSON.io.LimitReader
чтобы предотвратить это.Ответы:
Это действительно зависит от вашего вклада. Если вы посмотрите на реализацию
Decode
методаjson.Decoder
, он буферизует все значение JSON в памяти перед тем, как демонтировать его в значение Go. Так что в большинстве случаев он не будет более эффективным в использовании памяти (хотя это может легко измениться в будущей версии языка).Итак, лучшее эмпирическое правило таково:
json.Decoder
если ваши данные поступают изio.Reader
потока, или вам нужно декодировать несколько значений из потока данных.json.Unmarshal
если у вас уже есть данные JSON в памяти.В случае чтения из HTTP-запроса я бы выбрал,
json.Decoder
поскольку вы, очевидно, читаете из потока.источник
Buffered
метод позволяет вам увидеть любые дополнительные данные, которые были прочитаны во внутренний буфер после значения.