Go 打开切片的包装
我很好奇如何将一片切片解包并将它们作为参数发送给一个变量函数 假设我们有一个可变参数的函数:Go 打开切片的包装,go,slice,variadic-functions,Go,Slice,Variadic Functions,我很好奇如何将一片切片解包并将它们作为参数发送给一个变量函数 假设我们有一个可变参数的函数: func unpack(args ...interface{}) 如果我们不想传入一个接口片段,它就可以工作,那么解包与否无关紧要: slice := []interface{}{1,2,3} unpack(slice) // works unpack(slice...) // works 如果我们有一片一片的话,事情就变得棘手了。在这里,编译器不允许我们传入未打包的版本: sliceOfSlice
func unpack(args ...interface{})
如果我们不想传入一个接口片段,它就可以工作,那么解包与否无关紧要:
slice := []interface{}{1,2,3}
unpack(slice) // works
unpack(slice...) // works
如果我们有一片一片的话,事情就变得棘手了。在这里,编译器不允许我们传入未打包的版本:
sliceOfSlices := [][]interface{}{
[]interface{}{1,2},
[]interface{}{101,102},
}
unpack(sliceOfSlices) // works
unpack(sliceOfSlices...) // compiler error
错误显示:
无法将切片(类型[][]接口{})用作参数中的类型[]接口{}来解包
我不知道为什么会发生这种情况,因为我们可以清楚地将[]接口{}
类型传递到函数中。如何使用sliceOfSlices
的解包内容作为参数调用解包方法
操场示例:这在以下章节中介绍:
如果f
是可变的,且最后一个参数p
类型为…T
,则f
中p
的类型等同于类型[]T
如果最后一个参数可分配给切片类型[]T
,则如果该参数后跟..T
参数,则可以将其作为..T
参数的值不变地传递。在这种情况下,不会创建新切片
简而言之:这是一个编译时错误,因为不能将切片
(类型为[]interface{}
)分配给args
(类型为[]interface{}
)
长:
在您执行unpack(slice)
的第一个示例中,由于unpack()
需要interface{}
的值,因此slice
(类型为[]interface{}
)将被包装在一个新的interface{}
值中,并将作为单个参数传递
当您执行unpack(slice…
时,这将把slice
的所有值作为单独的值传递给unpack()
;这是可能的,因为切片的类型是[]接口{}
,它与可变参数的类型匹配(args…接口{}
)
在第二个示例中,当您执行unpack(sliceOfSlices)
时,sliceOfSlices
将被包装在一个新的接口{}
值中,并作为单个参数传递
但是当您尝试unpack(sliceOfSlices…
)时,会希望将sliceOfSlices的每个元素传递给unpack()
,但是sliceOfSlices的类型(即[]]接口{}
)与可变参数的类型不匹配,因此出现编译时错误
将切片
传递到解包()
“分解”的唯一方法是创建一个类型必须为[]接口{}
的新切片,复制元素,然后可以使用..
传递它
例如:
var sliceOfSlices2 []interface{}
for _, v := range sliceOfSlices {
sliceOfSlices2 = append(sliceOfSlices2, v)
}
unpack(sliceOfSlices2...)
试穿一下
让我们使用以下unpack()
函数来验证参数的数量:
func unpack(args ...interface{}) {
fmt.Println(len(args))
}
运行您的示例(并使用我的新切片创建),输出为:
1
3
1
2
在没有..
的情况下,只传递一个参数(包装在接口{}
中),并且使用..
将分别传递所有元素
在计算机上尝试此测试