我正在开发一个 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
,第二个版本似乎需要更少的代码,但是由于我已经看到了这两个版本,我想知道是否有任何偏好是否应该使用解决方案而不是其他解决方案。
此外,[这个问题的公认答案](https://stackoverflow.com/questions/15672556/handling-json- post-request-in-go)说
请使用
json.Decoder
而不是json.Unmarshal
.
但它没有提到原因。我真的应该避免使用json.Unmarshal
吗?
这真的取决于你的输入是什么。如果您查看Decode
方法的实现json.Decoder
,它会将整个 JSON 值缓冲在内存中,然后再将其解组为 Go
值。所以在大多数情况下,它不会提高内存效率(尽管这在未来的语言版本中很容易改变)。
所以一个更好的经验法则是:
如果json.Decoder
您的数据来自io.Reader
流,或者您需要从数据流中解码多个值,请使用此选项。
json.Unmarshal
如果内存中已有 JSON 数据,请使用。
对于从 HTTP 请求读取的情况,我会选择,json.Decoder
因为您显然是从流中读取的。