我正在学习 Go ,我对将slices
传递给函数表示怀疑。
如果我没错,slices
会在开始中通过引用传递,所以如果我这样做:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5}
fmt.Println(slice)
testSlice(slice)
fmt.Println(slice)
}
func testSlice(slice []int) {
slice[0] = 5
slice[4] = 1
}
testSlice
函数实际上会更改原始slice
中的值,因为它是通过引用传递的(默认情况下)。
有一种简单的方法可以直接将slice
的副本传递给testSlice
函数吗?
当然,我可以做这样的事情来创建slice
:
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5}
fmt.Println(slice)
testSlice(slice)
fmt.Println(slice)
}
func testSlice(slice []int) {
var newSlice []int
for i := 0; i < len(slice); i++ {
newSlice = append(newSlice, slice[i])
}
newSlice[0] = 5
newSlice[4] = 1
}
但它需要遍历原始slice
中的所有值才能复制每个值,这似乎不是一个很好的解决方案。
答案 0 :(得分:3)
内置函数copy
,func copy(dst, src []T) int
可能是您正在寻找的内容。它将任何类型的切片复制到另一个切片中。
来自docs:
复制功能支持在不同长度的切片之间进行复制(它只会复制到较少数量的元素)。此外,copy可以处理共享相同底层数组的源和目标切片,正确处理重叠切片。
所以
list := []string{"hello", "world"}
newList := make([]string, len(list))
n := copy(newList, list)
// n is the number of values copied
将list
复制到新的切片newList
中,该切片共享值而不是内存中的引用。 int
copy
返回的是复制值的数量。
另一种方法是,根据Kostix的评论,您可以将切片附加到空切片。这有点像复制它。它可能不是惯用的,但它允许您将切片作为副本传递给func
,类。如果你这样做,我建议大量的评论。
thisFuncTakesSliceCopy( append([]string(nil), list...) )
要将切片附加到另一个切片,请记住省略号(...
)。