Декодирование 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
?
Ответы
Ответ 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
используется, когда вход [] байт