英文:
Passing a collection of interface types to a function
问题
我在使用Go语言中的接口时遇到了一些困惑。我的函数需要接收一个实现了特定方法的项目映射。代码如下:
type foo interface {
bar() string
}
func doSomething(items map[string]foo) {
}
我试图使用实现了foo
接口的类型调用这个函数。
type baz struct { }
func (b baz) bar() string {
return "hello"
}
items := map[string]baz{"a": baz{}}
doSomething(items)
但是我得到了以下错误:
cannot use items (type map[string]baz) as type map[string]foo in function argument
然而,当我这样做时,它可以正常工作:
items := map[string]foo{"a": baz{}}
doSomething(items)
但是我想要重用同一个映射来满足不同的接口。基本上,我正在对许多对象进行索引,然后将它们传递给需要实现不同接口以计算结果的各种函数。我想要将映射作为foo
类型的映射传递给一个函数,作为foobar
类型的映射传递给另一个函数。
我尝试了各种类型断言和转换,但似乎没有任何有效的方法,所以我不确定是我使用的语法不正确还是完全错误。
你可以在Go Playground上查看示例代码:http://play.golang.org/p/8mMWCDG7vm。
英文:
I'm having trouble figuring out the correct way to use interfaces in Go. My function needs to take a map of items that implement a certain method. It looks like this:
type foo interface {
bar() string
}
func doSomething(items map[string]foo) {
}
I'm trying to call this function with a type that implements the foo
interface.
type baz struct { }
func (b baz) bar() string {
return "hello"
}
items := map[string]baz{"a": baz{}}
doSomething(items)
But I get the following error:
cannot use items (type map[string]baz) as type map[string]foo in function argument
However, it works fine when I do this:
items := map[string]foo{"a": baz{}}
doSomething(items)
But I want to reuse this same map against different interfaces. Basically I'm indexing a lot of objects and then passing them to various functions that require different interfaces implemented to compute results. I want to pass the map to one function as a map of foo
and another function as a map of foobar
.
I've tried various type assertions and conversions but nothing seems to work so I'm not sure if I'm just not using the correct syntax or just doing it completely wrong.
Go Playground at http://play.golang.org/p/8mMWCDG7vm.
答案1
得分: 2
这是一个相当常见的错误。
你混淆了这两种不同的类型:
map[string]foo
map[string]baz
你不能简单地从一个映射类型转换为另一个映射类型。同样的情况也适用于将[]T
切片转换为[]interface{}
切片,或者将chan T
转换为chan interface{}
(相同的问题/答案,但是针对通道)。
map[string]foo
表示一个foo接口的映射,而不是所有类型都是map[string]T,其中T实现了foo接口。
你可以通过进行以下更改来解决这个问题:
items := map[string]foo{"a": baz{}}
Playground: http://play.golang.org/p/HxIVGSptwk
编辑:
拥有一个接口的映射允许你将不同的接口值类型转换为其他类型的接口。因此,该映射可以被重复使用。
Playground: http://play.golang.org/p/20YMWmDjYT
但是,你应该拥有一个接口类型的映射,该接口类型是要存储在映射中的各种类型实现的方法的交集。如果没有交集,那么你将不得不使用interface{}
来确保任何类型都可以被存储。
英文:
This is a fairly common mistake.
You are mixing these two distinct types:
map[string]foo
map[string]baz
You cannot simply convert from one map type to another. The same goes with converting []T
slices to []interface{}
slices, or converting chan T
to chan interface{}
(same question/answer but for channels).
map[string]foo
means a map of foo interfaces, not all types map[string]T where T implements the foo interface.
You can solve it by making this change:
items := map[string]foo{"a": baz{}}
Playground: http://play.golang.org/p/HxIVGSptwk
Edit:
Having a map of interfaces allows you to type cast the different interface values to other types of interfaces. So the map can be reused.
Playground: http://play.golang.org/p/20YMWmDjYT
But then you should have a map of an interface type that is the intersection of all the different methods implemented by the types to be stored in the map. If there is no intersection, then you will have to use interface{}
to ensure that any type might be stored.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论