我正在开发一个API客户端,其中需要根据请求对JSON有效负载进行编码,并从响应中解码JSON正文.

我已经阅读了几个库中的源代码,从我所看到的情况来看,我基本上有两种编码和解码JSON字符串的可能性.

使用json.Unmarshal传递整个响应字符串

data, err := ioutil.ReadAll(resp.Body)
if err == nil && data != nil {
    err = json.Unmarshal(data, value)
}

or using json.NewDecoder.Decode

err = json.NewDecoder(resp.Body).Decode(value)

在我的例子中,当处理实现io.Reader的HTTP响应时,第二个版本似乎需要更少的代码,但由于我已经看到了这两个版本,我想知道是否有任何偏好,我是否应该使用一个解决方案而不是另一个.

此外,the accepted answer from this question表示

请用json.Decoder代替json.Unmarshal.

但它没有提到原因.我真的应该避免使用json.Unmarshal吗?

推荐答案

这真的取决于你的输入是什么.如果查看json.DecoderDecode方法的实现,它会在内存中缓冲整个JSON值,然后将其解组为Go值.因此,在大多数情况下,它的内存效率不会提高(尽管在future 的语言版本中,这很容易改变).

所以更好的经验法则是:

  • Use json.Decoder if your data is coming from an io.Reader stream, or you need to decode multiple values from a stream of data.
  • Use json.Unmarshal if you already have the JSON data in memory.

对于读取HTTP请求的情况,我 Select json.Decoder,因为您显然是从流读取的.

Json相关问答推荐

在Oracle中循环整个json_opp_t以更改特定键的值

PowerShell:将Invoke-WebRequest与变量一起使用

替换字符串中特殊字符的Jolt变换

如何用JQ更改空/布尔/数字的 colored颜色 ?

我发现GoFr响应总是包含在数据字段中,如何返回自定义响应?

使用JQ从jsonl文件中删除具有匹配键/值的行

将 std::可选值存储到 json 文件 C++

使用 jq,如何将两个属性构成键的对象数组转换为对象的索引对象?

JOLT转换并向输出添加新数组

如何在不使用 Newtonsoft.JSON 的情况下序列化/反序列化

使用带有逗号的字段名称构建 struct

hook到 Decodable.init() 以获得未指定的键?

python,将Json写入文件

如何将 LinkedHashMap 转换为自定义 java 对象?

如何在java中比较来自JsonObject的空值

我们可以使用 JSON 作为数据库吗?

Retrofit2.0 得到 MalformedJsonException 而 json 似乎正确?

Spring restTemplate 获取原始 json 字符串

在 Java 中比较两个 JSON 文件的最佳方法

字符串格式 JSON 字符串给出 KeyError