假设有一个通用接口:
type Packet interface {
Content() int
}
type Recycler[T any] interface {
Get() *T
}
及其实施:
type packet struct {
content int
}
type BaseRecycler[T any] struct {
t T
}
不可能将实现转换为接口:
r := &BaseRecycler[packet]{}
r1 := r.(Recycler[Packet])
fmt.Println(r3.Get().Content()) // compile error: Unresolved reference 'Content'
这是一个实时代码示例:https://go.dev/play/p/qbnYfyDd22A
错误是因为
Packet
界面与*packet
而不是packet
对齐。有人可以建议如何处理这个问题吗?
您可以通过从
*Packet
取消引用 Packet
(指向 r3.Get()
接口的指针)来修复编译错误:
r := &BaseRecycler[packet]{}
var r1 interface{} = r
r3 := r1.(Recycler[Packet])
fmt.Println((*r3.Get()).Content())
根据接口的定义,您可以在生成的
Content()
(接口)上调用 Packet
。
不幸的是,这不是一个解决方案,因为上一行发生了运行时错误。您不能使用 类型断言 将
*BaseRecycler[packet]
转换为 Recyler[Packet]
,因为它们是不兼容的类型(请注意数据包的大小写)。您可以使用 r
(接口)重新声明 Packet
,使其正常工作:
r := &BaseRecycler[Packet]{
t: &packet{},
}
var r1 interface{} = r
r3 := r1.(Recycler[Packet])
fmt.Println((*r3.Get()).Content())
权衡是代码示例的其他部分将不再编译,原因类似:
r2 := r1.(Recycler[packet])
fmt.Println(r2.Get().Content())
希望您的用例不需要这两种类型断言。