为何Go中类型参数无法调用其类型集的方法?
为什么Go泛型中用具体类型做约束时无法调用方法?
先看你给出的报错代码:
type A int func (A) Hi() { } func DoA[T A](t T) { t.Hi() // 编译错误:t.Hi undefined (type T has no field or method Hi) }
明明T的约束是A,t只能是A的实例,但调用t.Hi()却报错。换成接口约束就正常:
type I interface{ Hi() } func DoA[T I](t T) { t.Hi() // 编译通过 }
原因很直接:Go泛型对具体类型约束和接口约束的处理逻辑完全不同。
- 当约束是具体类型(比如
T A)时,类型参数T的方法集是空的。Go的方法是绑定到具体类型上的,即便T只能是A,编译器也不会把A的方法“关联”给T这个类型参数。在泛型函数的编译阶段,编译器只认约束里明确声明的内容——具体类型约束没有声明任何方法,所以它判定T没有Hi()方法。 - 当约束是接口类型(比如
T I)时,接口明确列出了Hi()方法,编译器清楚所有符合约束的类型都必须实现这个方法,因此允许正常调用t.Hi()。
如果想在具体类型约束下调用方法,还有个变通办法:把类型参数显式转换为A,比如:
func DoA[T A](t T) { A(t).Hi() // 这样就能正常编译 }
转换后得到的是具体类型A的实例,自然拥有Hi()方法。
内容的提问来源于stack exchange,提问作者lianggo
相关产品推荐
相关产品推荐

