Passing a collection of interface types to a function

青春壹個敷衍的年華 提交于 2021-02-08 06:36:39

问题


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:


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.



来源:https://stackoverflow.com/questions/22825873/passing-a-collection-of-interface-types-to-a-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!