今天尝试把工程从古老的1.13
版本升级到最新的1.20
,打算坐下泛型
的快车。升级之后运行时立马就panic
掉了。打印堆栈日志,发现是内部common库
依赖的github.com/json-iterator/go@v1.1.10
导致的。翻了翻源码,问题出在github.com/json-iterator/go@v1.1.10/reflect_map.go:333
这里的mapType
使用了reflect2
(github.com/modern-go/reflect2@v1.0.1
),追根溯源
这里reflect2
弄了个骚操作
利用go:linkname
这个编译器指令,骗过编译器检查直接使用了reflect.mapiterinit
。其具体含义:
mapiterinit
函数是一个与reflect
包中的mapiterinit
函数相关联的低级函数,用于初始化 map 的迭代器。它利用了 Go 编译器的go:linkname
指令,以便在reflect2
包中直接调用 Go 运行时(runtime)中实现的reflect.mapiterinit
函数。
而go1.18
版本将reflect.map.iterinit
做了调整
显然go1.18
将mapiterinit
新增了一个参数,但是因为reflect2
使用了骚操作,骗过了编译器,但运行时panic
。
解决办法:
目前json-iterator
和reflect2
均已兼容go1.18
升级到最新版本即可