英文:
Can't pass slices of structs implementing the Foo interface to a function that expects []Foo
问题
我正在尝试在Go语言中使用接口,但似乎无法将实现某个接口的结构体切片传递给期望接口切片的函数。对于只接受单个对象的函数,它可以正常工作,但对于期望接口切片的函数则不行。使用下面的代码,我得到以下错误信息:
./main.go:27: cannot use fooBar (type []*FooBar) as type []Foo in argument to FooBarBar
以下是代码:
package main
import "fmt"
type Foo interface {
Bar() bool
}
type FooBar struct {
a bool
}
func (f *FooBar) Bar() bool {
return f.a
}
func FooBarBar(foos []Foo) {
for _, foo := range foos {
fmt.Println(foo.Bar())
}
}
func main() {
fooBar := make([]*FooBar, 2)
fooBar[0] = &FooBar{true}
fooBar[1] = &FooBar{false}
FooBarBar(fooBar)
}
英文:
I'm trying to work with interfaces in Go but I can't seem to be able to pass a slice of structs implementing a certain interface to a function that expects a slice of the interface. It works with functions that just takes a single object but not with functions expecting slices of the interface. Using the code below I get the following error:
> ./main.go:27: cannot use fooBar (type []*FooBar) as type []Foo in argument to FooBarBar
Here is the code:
package main
import "fmt"
type Foo interface {
Bar() bool
}
type FooBar struct {
a bool
}
func (f *FooBar) Bar() bool {
return f.a
}
func FooBarBar(foos []Foo) {
for _, foo := range foos {
fmt.Println(foo.Bar())
}
}
func main() {
fooBar := make([]*FooBar, 2)
fooBar[0] = &FooBar{true}
fooBar[1] = &FooBar{false}
FooBarBar(fooBar)
}
答案1
得分: 1
在Go语言中,没有"子类型化"的概念。
[]Foo
和[]*Foobar
是两种不同的类型,所以你只能使用for循环将[]*Foobar
转换为[]Foo
:
foos := []Foo{}
for _, f := range foobar {
foos = append(foos, f)
}
FooBarBar(foos)
或者你可以直接将*Foobar
放入[]Foo
切片中:
foos := []Foo{&FooBar{true}, &FooBar{false}}
FooBarBar(foos)
还有一些例外情况,比如命名类型和未命名类型之间的关系:
type FooBar struct{}
type Foobars []*FooBar // Foobars是一个命名类型,[]*FooBar是一个未命名类型
AcceptFoobars := func(f []*FooBar) {} // 也接受Foobars类型
foobars := Foobars{{}, {}, {}}
AcceptFoobars(foobars)
Go语言的类型系统是"扁平的",没有继承或类型转换,只有断言和转换,这是Go语言规范中定义的。
参考链接:https://golang.org/ref/spec#Types
类型确定了特定类型的值和操作集。类型可以是命名的或未命名的。命名类型由(可能是限定的)类型名称指定;未命名类型使用类型字面量指定,它从现有类型组合成一个新类型。
英文:
There is no "sub typing" in Go.
[]Foo
and []*Foobar
are 2 different types, so all you can do is use a for loop to convert []*Foobar
into []Foo
foos := []Foo{}
for _,f:=range foobar {
foos = append(foos,f)
}
FooBarBar(foos)
Or you can put your *Foobar directly in a slice of Foo :
foos := []Foo{&FooBar{true},&FooBar{false}}
FooBarBar(foos)
There are a few exceptions like the relationship between named types and unnamed types
type FooBar struct{}
type Foobars []*FooBar // Foobars is an named type, []*FooBar is an unnamed type
AcceptFoobars := func(f []*FooBar) {} // Accepts Foobars too
foobars := Foobars{{}, {}, {}}
AcceptFoobars(foobars)
Go type system is "flat", there is no inheritance or casting, only assertions and conversions. as defined by the Go spec.
https://golang.org/ref/spec#Types
> A type determines the set of values and operations specific to values
> of that type. Types may be named or unnamed. Named types are specified
> by a (possibly qualified) type name; unnamed types are specified using
> a type literal, which composes a new type from existing types.
答案2
得分: 0
可以试试这种方式吗:
func main() {
fooBar := []Foo{&FooBar{true}, &FooBar{false}}
FooBarBar(fooBar)
}
英文:
Can i try this way:
func main() {
fooBar := []Foo{&FooBar{true}, &FooBar{false}}
FooBarBar(fooBar)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论