encoding/json: Map key marshals with MarshalText but unmarshals with UnmarshalJSON #29732
Comments
Perhaps a duplicate of #23455? |
Thanks for the link, @mvdan. That issue seems to be describing a type which implements UnmarshalJSON but not UnmarshalText. In my case, my type implements both interfaces. Decode correctly checks if the map key type implements UnmarshalText, but if yes it eventually attempts UnmarshalJSON instead (if both are implemented). |
From the current documentation for
Note that in your example, the map's key type itself does not implement |
At any rate, removing the |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What did you do?
playgound: https://play.golang.org/p/4g3sHaRjh7z
MarshalJSON
,UnmarshalJSON
,MarshalText
,UnmarshalText
, where the JSON form is an object, not string.json.Marshal
the map. Notice the MarshalText behavior is used to convert the map keys to strings in the resulting JSON object.json.Unmarshal
the JSON bytes from (3) into a new map.What did you expect to see?
json.Unmarshal
should use the map key'sUnmarshalText
method, because it is forced to be a JSON string.What did you see instead?
json.Unmarshal
used the type'sUnmarshalJSON
method on the map key data.Debugging
TextMarshaler map keys were introduced in ffbd31e. The core issue is that
literalStore
always prefersUnmarshalJSON
(decode.go#L855) before attemptingUnmarshalText
becauseindirect
only returns one of the interfaces and prefers JSON to Text. This is correct in most cases, but for map keys we're calling literalStore explicitly because the value implements UnmarshalText (decode.go#L776).The text was updated successfully, but these errors were encountered: