如何将切片的副本传递给函数?

时间:2017-04-21 15:36:07

标签: go slice

我正在学习 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中的所有值才能复制每个值,这似乎不是一个很好的解决方案。

1 个答案:

答案 0 :(得分:3)

内置函数copyfunc 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...) )

要将切片附加到另一个切片,请记住省略号(...)。