inconsistent behavior of json.Unmarshal into a map with custom types vs into a struct or slice

Viewed 77

I have a custom type, which is supposed to be an enumerator, and it implements json.Unmarshaler.

When I unmarshal into a slice, or a struct of this type, it works, like https://go.dev/play/p/DGg3nzo_VwN

When I unmarshal into a map containing this type, it breaks, like https://go.dev/play/p/YGgnRvr0agz

Crawling through the source code (go 1.18), I know how to make it work, just implement encoding.TextUnmarshaler, like https://go.dev/play/p/vY4E4snAY52 and I also have learned how the code works for maps: it checks if encoding.TextUnmarshaler is implemented, if yes, call its UnmarshalJSON before trying UnmarshalText. In other words, UnmarshalText must be present, however it will be ignored if UnmarshalJSON is also present.

Why is this precedence? Why only maps are treated this way?

1 Answers

From Go's decoder:

// Map key must either have string kind, have an integer kind,
// or be an encoding.TextUnmarshaler.

So you must implement TextUnmarshaller.

Related