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

huangapple go评论74阅读模式
英文:

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

问题

我有一个自定义类型,应该是一个枚举器,并且它实现了json.Unmarshaler。

当我将其反序列化为切片或者结构体时,它可以正常工作,就像这个例子:https://go.dev/play/p/DGg3nzo_VwN

但是当我将其反序列化为包含该类型的映射时,它就会出错,就像这个例子:https://go.dev/play/p/YGgnRvr0agz

通过查看源代码(go 1.18),我知道了如何使其正常工作,只需实现encoding.TextUnmarshaler,就像这个例子:https://go.dev/play/p/vY4E4snAY52。我还了解了映射的工作原理:它会检查是否实现了encoding.TextUnmarshaler,如果是,则在尝试UnmarshalText之前调用其UnmarshalJSON。换句话说,UnmarshalText必须存在,但如果UnmarshalJSON也存在,它将被忽略。

为什么会有这种优先级?为什么只有映射会被这样处理?

英文:

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

得分: 1

从Go的decoder中:

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

所以你必须实现TextUnmarshaller。

英文:

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.

huangapple
  • 本文由 发表于 2022年7月16日 01:19:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/72997625.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定