Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Interface 将接口类型集合传递给函数_Interface_Go - Fatal编程技术网

Interface 将接口类型集合传递给函数

Interface 将接口类型集合传递给函数,interface,go,Interface,Go,我很难找到在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{"

我很难找到在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
的映射传递给另一个函数

我尝试过各种类型断言和转换,但似乎都不起作用,所以我不确定我是没有使用正确的语法,还是完全错了


去操场。

这是一个相当常见的错误

您正在混合这两种不同的类型:

map[string]foo

map[string]baz
不能简单地从一种贴图类型转换为另一种贴图类型。或(相同的问题/答案,但针对频道)

map[string]foo
表示foo接口的映射,而不是所有类型的映射[string]T,其中T实现foo接口

type baz struct { }

func (b baz) bar() string {
    return "hello"
}

items := map[string]baz{"a": baz{}}
doSomething(items)
您可以通过进行以下更改来解决此问题:

items := map[string]foo{"a": baz{}}
操场:

编辑:

拥有接口映射允许您将不同的接口值类型转换为其他类型的接口。因此,地图可以重复使用

操场:


但是您应该有一个接口类型的映射,它是由要存储在映射中的类型实现的所有不同方法的交集。如果没有交叉点,那么您必须使用
接口{}
来确保可以存储任何类型。

我知道
map[string]foo
可以工作(请参见我原来的问题),但我希望我遗漏了什么。处理需要使用接口传递的结构集合的惯用方法是什么?是否为每种接口类型重新创建整个映射?以某种方式为映射类型创建一个接口?如果您要传递它,我建议仍然将其作为接口映射。如果您这样做,您可以在需要时将值转换为
foobar
:参见编辑示例。啊,我明白了。想要接口foobar似乎很奇怪,但接受接口foo只是为了以后可以将其转换为所需的接口。表示即使所需的接口类型是静态的,也不进行编译时类型检查。是的,在这种情况下,这很奇怪。我刚刚添加到编辑中,您可能希望为映射值使用不同的接口,以确保应该存储在映射中的任何类型都实际实现了该接口。比如,如果您要存储io.Writer,有时还要存储io.ReadWriter,那么您需要使用io.Writer接口,因为它是由您要存储的所有类型实现的。