According to the documentation for json.Unmarshal:
"To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match."
However the library will use the last instance of the field.
I think this is working as expected. The package prefers an exact match in the sense of matching the JSON key against the field name. That is, the text is describing which field to use for a JSON key.
In this case, every JSON key matches the single field. Each is applied in turn, and the last one remains.
@ianlancetaylor I think the documentation should be updated instead as it is misleading. It puts forward two possibilities for how a field is updated, one 'exact' and the other 'case insensitive', but both are in fact case insensitive matches.
I'm sorry, I don't understand what you mean. The documentation is describing how it unmarshals into a struct. Given a JSON key, which field will be the value be placed in? It first looks for a field whose name (or tag) exactly matches the value. If it doesn't find one, it looks for a field that matches using a case insensitive comparison. It is not the case that both matches are case insensitive.
Can you offer a suggestion as to how to improve the documentation?
Ok I understand now, please disregard my previous comment. I think the confusion arises because it is not clear from the documentation in which domain (incoming object key or struct field/tag) the operation for matching happens in. I had initially thought the order of preference was with regard to JSON tags, not field names. I can see this being a common misinterpration, maybe it should be clarified?
"To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring a destination key with an exact match but also accepting a case-insensitive match." ?