今天看 leader 的一个提交在使用 Go 语言的 Struct 时用了一个比较神奇的 tag 用法,类似于下面这种方式:

// created by https://liqiang.io
type A struct {
	A int `json:"a,string"`
	B int `json:"b"`
}

这里的 A.A 的类型是 int,但是 tag 里面的标记却是 string 类型,然后使用的时候是这么用的:

// created by https://liqiang.io
func main() {
	str := `{"a": "10", "b": 10}`
	var a A
	err := json.Unmarshal([]byte(str), &a)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", a)
}

然后对应的输出结果为:{A:10 B:10},可以发现,这个可以解析 string 类型为 int 类型,也就是说内部做了自行转换。但是,当你指定了这个 tag 之后,就不能解析 int 了,例如这样就会报错:

// created by https://liqiang.io
func main() {
	str := `{"a": 10, "b": 10}`
	var a A
	err := json.Unmarshal([]byte(str), &a)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", a)
}

执行一下你就会发现,报错的内容就是类型不符合;

panic: json: invalid use of ,string struct tag, trying to unmarshal unquoted value into int

goroutine 1 [running]:
main.main()
	......./json/main.go:19 +0x147

Process finished with exit code 2

所以这里其实 json 就把这个类型认为是 string 的输入,int 的输出了。