为啥 Go 编译器不能推断结构实现了接口 [关闭]
Posted
技术标签:
【中文标题】为啥 Go 编译器不能推断结构实现了接口 [关闭]【英文标题】:Why can't Go compiler deduce that a struct implements an interface [closed]为什么 Go 编译器不能推断结构实现了接口 [关闭] 【发布时间】:2021-12-30 09:33:10 【问题描述】:运行下面的代码会导致编译错误:
不能在返回参数中使用作者(类型 []Person)作为类型 []Namer
为什么不能Go编译?
type Namer interface
Name() string
type Person struct
name string
func (r Person) Name() string
return r.name
func Authors() []Namer
// One or the other is used - both are not good:
authors := make([]Person, 10)
var authors []Person
...
return authors
将authors
声明为authors := make([]Namer, 10)
或var authors []Namer
可以,但我不明白为什么编译器不能推断Person
是Namer
。
【问题讨论】:
golang.org/doc/faq#convert_slice_of_interfacePerson
不是 Namer
。它们是不同的类型。 Person
确实实现了Namer
接口,但这仅意味着Person
的值可以分配给Namer
类型的值。它对类型等价没有任何一般含义,例如您在此处显示的复合类型。这就是为什么需要深度转换(参见 Cerise 的评论)
这能回答你的问题吗? Type converting slices of interfaces
【参考方案1】:
因为[]Person
不是[]Namer
。让我们把你的例子更进一步:
type Namer interface
Name() string
type Person struct
name string
func (r Person) Name() string
return r.name
type Thing struct
name string
func (t Thing) Name() string
return r.name
func Authors() []Namer
authors := make([]Person, 10)
return authors
func main()
namers := Authors()
// Great! This gives me a []Namer, according to the return type, I'll use it that way!
thing := Thing
namers := append(namers, thing)
// This *should* work, because it's supposed to be a []Namer, and Thing is a Namer.
// But you can't put a Thing in a []Person, because that's a concrete type.
如果代码期望收到[]Namer
,那就是它必须得到的。不是 []ConcreteTypeThatImplementsNamer
- 它们不可互换。
【讨论】:
以上是关于为啥 Go 编译器不能推断结构实现了接口 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章