-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
encoding/json: unclear documentation for how json.Unmarshal
and json.Unmarshaler
interact with null
#48646
Comments
You're unmarshaling into a pointer, and as per the docs you quoted, that gets set to nil when unmarshalling The "by convention" bit is from f444b48. It does seem inconsistent at first sight, but note that it says "to approximate". My guess is that that's the best option we have - if you read the commit message, you'll see why we must always call If we made the two cases explicitly consistent, then I'm definitely open to suggestions to make the docs clearer. Though I don't think explaining all this nuance in detail in the godoc is a good idea :) cc @dsnet |
Hi @mvdan, thanks for getting back to me so quickly! I had a look at f444b48 and I think I my confusion stemmed from not having a clear understanding of the different approaches to unmarshaling null into values and pointers. As I understand it unmarshaling null into a pointer sets that pointer to nil, whereas unmarshaling null into a value leaves the value untouched. I think this behaviour could be made a little more explicit in the doc for Something like:
Also I'm not 100% sure I follow the reasoning for raw message not working if UnmarshalJSON is not called on nulls, could you elaborate a bit? |
RawMessage is a slice, so if the regular rules were followed, then unmarshaling
Did you verify that this is the case? The way you modified the first sentence makes sense to me. Just beware that it's not just about pointers - the regular rules include all nilable type kinds that json knows how to work with: interfaces, maps, pointers, and slices. So it's slightly wrong if you talk about "pointer" and "non-pointer". Perhaps it would be more correct to modify the first sentence to say nilable or "pointer-like". Would like to hear @dsnet's thoughts too. |
Hi @mvdan, thank you for clarifying that.
This is the code l used to verify this - https://play.golang.org/p/jD7nQmcKlwL Thanks for pointing out that it's more than just pointer or non pointer. I actually don't think nillable can be used either, since we can see from the code example that the Given this, I think the following could be a more correct attempt to make the docs clearer.
|
json.Unmarshal
and json.Unmarshaler
interact with null
CC @dsnet |
The documented rules in As such, the 4th paragraph says:
While, it is the 11th paragraph that says:
Therefore, the presence of an I don't think the 11th paragraph should have anything about |
@dsnet maybe we should clarify that "the following rules" apply from highest to lowest priority. I was probably reading them as if they were an unordered set. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Ran this code - https://play.golang.org/p/dHiWmj8X7KD
Which shows
json.Unmarshal
overwriting a struct with nil when passed[]byte("null")
What did you expect to see?
I'm not sure exactly.
The go-playground example seems to be operating correctly if looking at the documentation for json.Unmarshal
But if looking at the documentation for json.Unmarshaller, it seems to not be operating correctly since it states that using json.Unmarshal to unmarshal
[]byte("null")
should be a no-op.What did you see instead?
json.Unmarshal
overwriting a struct with nil when passed[]byte("null")
The text was updated successfully, but these errors were encountered: