Подтвердить что ты не робот

Декодирование JSON в Голанге с использованием json.Unmarshal vs json.NewDecoder.Decode

Я разрабатываю клиент 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?

4b9b3361

Ответ 1

Это действительно зависит от вашего ввода. Если вы посмотрите на реализацию метода Decode json.Decoder, он буферизует все значение JSON в памяти перед тем, как развязать его в значение Go. Таким образом, в большинстве случаев он не будет более эффективным с точки зрения памяти (хотя это может легко измениться в будущей версии языка).

Итак, лучшее эмпирическое правило:

  • Используйте json.Decoder, если ваши данные поступают из потока io.Reader или вам необходимо декодировать несколько значений из потока данных.
  • Используйте json.Unmarshal, если у вас уже есть данные JSON в памяти.

В случае чтения из HTTP-запроса я бы выбрал json.Decoder, поскольку вы явно читаете из потока.

Ответ 2

Мы должны получить [] байт из трубы перед декодированием, поэтому чтение из io необходимо при работе с HTTP-соединениями, поэтому я думаю, что две функции равны. Но когда данные сохраняются в памяти или у нас есть [] байт, мы можем использовать Unmarshal напрямую, это лучше.

json.Decoder используется при чтении и записи HTTP-соединений, WebSockets или файлов.

json.Unmarshal используется, когда вход [] байт