使用空接口的时候一定注意其运行时类型,Golang没有自动转换。
专栏的介绍可以参考 《GotchaGolang专栏》,代码可以看《宝库-Gotcha》。
记录碰到的关于 interface 运行时类型的问题。
案例
话不多说,直接上代码: (两份代码相比较,应该能看出问题吧)
1 | package main |
编译时直接报错了,意思是说,e 的类型是 interface{}
但是却用于 if 条件语句。
反射得到的结果是 e 的运行时类型,怎么跳过编译器编译检查呢?(编译检查的是原始类型不是运行时类型)
方式一: (type assertion)
1 | //way one: type assertion |
需要担心的是,类型断言如果失败,直接 panic
方式二: (using == to get the runtime type)
1 | //way two: using == to get the runtime type |
编译器之所以报错是因为编译器不对 interface{} 接口实现的类型做任何 automatic change/convert。
但是 e == true
相当于让一个 interface{} 和 bool 类型进行比较,这就要检查运行时类型了,所以编译器不多说话。
官方文档: 如果一个 non-interface X 和 interface T 比较。如果 X 实现了 T 接口,则可以进行比较,因为他们 dynamic type is identical/equals. (运行时类型兼容或者相同既可以比较, 所以利用 == 来检查运行时类型接口)
完整代码如下:
1 | package main |
总结
interface{}
本身不携带任何类型信息(编译时), 并且编译时不会去检查运行时实际类型。
所以当你要使用其运行时类型信息,那么 access to it,就像上面的 ==
比较的时候,就会取其运行时类型。
教训是:偷懒的写法,你确定不会出问题?但凡有一丝疑虑,就要仔细推敲一下。
Merlin 2018.3 Golang 坑