I'm developing an API client where I need to encode a JSON payload on request and decode a JSON body from the response.
I've read the source code from several libraries and from what I have seen, I have basically two possibilities for encoding and decoding a JSON string.
Use json.Unmarshal
passing the entire response string
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)
In my case, when dealing with HTTP responses that implements io.Reader
, the second version seems to be require less code, but since I've seen both I wonder if there is any preference whether I should use a solution rather than the other.
Moreover, the accepted answer from this question says
Please use
json.Decoder
instead ofjson.Unmarshal
.
but it didn't mention the reason. Should I really avoid using json.Unmarshal
?
转载于:https://stackoverflow.com/questions/21197239/decoding-json-in-golang-using-json-unmarshal-vs-json-newdecoder-decode
It really depends on what your input is. If you look at the implementation of the Decode
method of json.Decoder
, it buffers the entire JSON value in memory before unmarshalling it into a Go value. So in most cases it won't be any more memory efficient (although this could easily change in a future version of the language).
So a better rule of thumb is this:
json.Decoder
if your data is coming from an io.Reader
stream, or you need to decode multiple values from a stream of data.json.Unmarshal
if you already have the JSON data in memory.For the case of reading from an HTTP request, I'd pick json.Decoder
since you're obviously reading from a stream.
We must get []byte from the pipe before decode, so read from io is necessary when deal with HTTP connections, so i think the two function is equal. But when the data has save in memory, or we have get the []byte, we can use Unmarshal
directly, it is better.
The json.Decoder
is used when reading and writing to HTTP connections, WebSockets, or files.
The json.Unmarshal
is used when the input is []byte