这个坑隐藏得很深,绝大多数情况下都不会碰到。在转换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. By default, object keys which don’t have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).

精确匹配最好,但是也接受大小写不敏感的匹配。只能说“包容性”太好了,但我认为这并不是一个好的设计。

一段典型代码如下:

package main

import (
	"encoding/json"
	"fmt"
)

type UserInfo struct {
	UserID string `json:"UserID"`
}

func main() {
	var u1 UserInfo
	json.Unmarshal([]byte(`{"UserID":"aaa"}`), &u1)
	fmt.Println(u1.UserID)  // 打印 aaa

	var u2 UserInfo
	json.Unmarshal([]byte(`{"UserID":"aaa", "UserId":"bbb"}`), &u2)
	fmt.Println(u2.UserID)  // 打印 bbb

	var u3 UserInfo
	json.Unmarshal([]byte(`{"UserID":"aaa", "UserId":"bbb", "userId":"ccc"}`), &u3)
	fmt.Println(u3.UserID)  // 打印 ccc
}
Tags:

1 Comment

  1. 刚碰到一个“这也能正常运行?!”的问题,一查就是这个坑…

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.