使用json.Unmarshal vs json.NewDecoder.Decode解码Golang中的JSON
我正在开发一个API客户端,我需要根据请求对JSON负载进行编码,并从响应中解码JSON主体。
我已经阅读了几个库的源代码,从我所看到的,我基本上有两种编码和解码JSONstring的可能性。
使用json.Unmarshal
传递整个响应string
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响应时,第二个版本似乎需要更less的代码,但是因为我已经看到了两者,我想知道是否应该使用解决scheme,而不是使用其他解决scheme。
而且, 从这个问题接受的答案说
请使用
json.Decoder
代替json.Unmarshal
。
但没有提到原因。 我真的应该避免使用json.Unmarshal
?
这真的取决于你的input是什么。 如果您查看json.Decoder
的Decode
方法的json.Decoder
,它会将整个JSON值caching到内存中,然后将其解组为一个Go值。 所以在大多数情况下,它不会有更高的内存效率(尽pipe在未来的语言版本中这很容易改变)。
所以一个更好的经验法则是:
- 如果数据来自
io.Reader
stream,则使用json.Decoder
,或者需要解码来自数据stream的多个值。 - 如果您已经在内存中有JSON数据,请使用
json.Unmarshal
。
对于从HTTP请求读取的情况,我会selectjson.Decoder
因为您显然正在读取stream。
我们必须在解码之前从pipe道获取[]字节,所以在处理HTTP连接时需要从io读取,所以我认为这两个函数是相等的。 但是当数据保存在内存中,或者我们已经得到了[]字节的时候,我们可以直接使用Unmarshal
,这样比较好。
在读取和写入HTTP连接,WebSockets或文件时使用json.Decoder
。
当input是[]字节时使用json.Unmarshal