使用json.Unmarshal vs json.NewDecoder.Decode解码Golang中的JSON

时间:2014-01-17 22:34:56

标签: json go

我正在开发一个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)

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

此外,the accepted answer from this question

  

请使用json.Decoder代替json.Unmarshal

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

2 个答案:

答案 0 :(得分:184)

这实际上取决于您的输入。如果查看Decode json.Decoder方法的实现,它会将整个JSON值缓存到内存中,然后再将其解组为Go值。因此,在大多数情况下,它将不再具有更高的内存效率(尽管在未来的语言版本中这很容易改变)。

所以更好的经验法则是:

  • 如果您的数据来自json.Decoder流,或者您需要解码数据流中的多个值,请使用io.Reader
  • 如果您已在内存中安装了JSON数据,请使用json.Unmarshal

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

答案 1 :(得分:0)

<块引用>

我在 Go 网络编程书中找到了这一段。但是没有给出解释

那么我们什么时候使用解码器和解组?

这取决于输入。如果您的数据来自 io.Reader 流,例如 http.Request 的正文,请使用解码器。如果您的数据位于字符串中或内存中的某处,请使用 Unmarshal。