传播

时间:2019-09-02 00:34:36

标签: go slice

原型功能

func test(i ...interface{}) {
    // Code here
}

预期用途

type foo struct {
    // Fields
}

foos := []foo{
    // foo1, foo2 ...
}

test(foos...) // ERROR
test(foos[1], foos[2], ...) // OK

错误

  

不能在测试参数中使用foos([] foos类型的变量)作为[] interface {}值

说明

预期用途将与内置功能append()一样使用。

https://golang.google.cn/pkg/builtin/#append

func append(slice []Type, elems ...Type) []Type

尽管,正如我所见,append()没有使用interface{},这很奇怪,因为在我搜索过的任何地方,所有人都不知道时会说interface{}方式。但是他们没有。 不,append()使用一种名为Type的“内置”类型,很显然文档说它是int。虽然,我不能使用它。没有这种类型。而且如果有的话,我也不知道如何使用。

https://golang.google.cn/pkg/builtin/#Type

type Type int

所以,我在这里很困惑。

问题

  1. 为什么散布运算符不能按预期工作?例如,在Javascript中,spread运算符只是将数组扩展为项目。但是在Golang中,它似乎保持了与相同的数组参数类型,但是稍后向编译器提供了扩展它的指令。真奇怪。

  2. 我们是否甚至能够建立类似append()之类的自定义机制?还是我是个假人,反正我使用了错误的东西?

3 个答案:

答案 0 :(得分:2)

我认为这是您在这里遇到的问题。

https://github.com/golang/go/wiki/InterfaceSlice

我不是专家,但是之前曾打过,“空接口片”不是接口,因此不能用任何类型的替换,这是您遇到的问题,它与内存结构不同。上面的解释比我能提供的要好得多。

答案 1 :(得分:0)

您可以键入键入的切片以获得所需的内容:

generic := make([]interface{}, 0)
for _, f := range foos {
  generic = append(generic, f)
}
test(generic...)  // works

答案 2 :(得分:0)

将两个非否定的答案组合成我认为的最佳解决方案:

interfaceSlice := make([]interface{}, len(foos))
for i, v := range foos {
    interfaceSlice[i] = v
}
test(interfaceSlice...)

部分灵感来自:

https://github.com/golang/go/wiki/InterfaceSlice#what-can-i-do-instead