在golang中连接2个切片

imp*_*ble 2 go slice

我有2片,

s1 := []int{1, 2, 3, 4, 5}
s2 := []int{3, 4, 5, 6, 7}
Run Code Online (Sandbox Code Playgroud)

我想要结果

s3 = []int{1, 2, 3, 4, 5, 3, 4, 5, 6, 7}
Run Code Online (Sandbox Code Playgroud)

我做的事情如下:

for _, x := range s1 {
        s2 = append(s2, x)
    }
Run Code Online (Sandbox Code Playgroud)

这看起来非常简单,但相信我,我找不到一个单行解决方案.我们怎么能这样呢?

icz*_*cza 9

这就是内置append()函数的用途:将值(可能是切片的值)附加到另一个的末尾.结果是连接.

如果你想s3成为"独立"的s1s2,然后附加s1到一个空或nil切片,然后附加s2到的结果:

s3 := append(append([]int{}, s1...), s2...)
fmt.Println(s3)
Run Code Online (Sandbox Code Playgroud)

如果s3可以使用/重叠s1,您可以简单地附加s2s1:

s4 := append(s1, s2...)
fmt.Println(s4)
Run Code Online (Sandbox Code Playgroud)

两种情况下的输出(在Go Playground上尝试):

[1 2 3 4 5 3 4 5 6 7]
Run Code Online (Sandbox Code Playgroud)

注意:这种"重叠"的含义是,如果您附加值s1,如果它具有足够的容量,则不会分配新的切片,s1将被重新调整以具有足够的长度来容纳您想要附加到它的元素.如果使用不明智,这可能会产生令人惊讶的副作用,如下例所示:

arr := [...]int{1, 2, 3, 4, 5, 6, 7, 0, 0, 0}

s1 := arr[:5]
s2 := arr[2:7]
fmt.Println("s1:", s1, "cap:", cap(s1))
fmt.Println("s2:", s2)

s3 := append(s1, s2...)
fmt.Println("s3:", s3)

fmt.Println("s2:", s2)
Run Code Online (Sandbox Code Playgroud)

输出是(在Go Playground上试试):

s1: [1 2 3 4 5] cap: 10
s2: [3 4 5 6 7]
s3: [1 2 3 4 5 3 4 5 6 7]
s2: [3 4 5 3 4]
Run Code Online (Sandbox Code Playgroud)

什么可以奇怪这里要说的是,当我们追加s2s1并存储在结果s3(这是我们所期望的),内容(元素)s2也发生了变化.原因是append()s1有足够的能力附加s2到它(元素s2),所以它没有创建一个新的数组,它只是复制s1并添加元素"就地".但是编写附加元素的区域与s2驻留元素完全相同,因此元素s2也被覆盖.