英文:
Why can't Go compiler deduce that a struct implements an interface
问题
运行下面的代码将导致编译错误:
> 无法将 authors(类型 []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
。
英文:
Running the code below will result in a compilation error:
> cannot use authors (type []Person) as type []Namer in return argument
Why can't Go compile it?
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
Declaring authors
as authors := make([]Namer, 10)
or var authors []Namer
would be fine, but I can't see why the compiler cannot infer that Person
is Namer
.
答案1
得分: 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()
// 太好了!根据返回类型,这给了我一个[]Namer,我会按照这种方式使用它!
thing := Thing{}
namers := append(namers, thing)
// 这应该可以工作,因为它应该是一个[]Namer,而Thing是一个Namer。
// 但是你不能把Thing放在[]Person中,因为那是一个具体类型。
}
如果代码期望接收一个[]Namer
,那就必须得到一个[]Namer
。不能使用[]ConcreteTypeThatImplementsNamer
,它们不能互换。
英文:
Because a []Person
is not a []Namer
. Let's take your example one step further:
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.
}
If code expects to receive a []Namer
, that is what it must get. Not []ConcreteTypeThatImplementsNamer
- they're not interchangeable.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论