【发布时间】:2016-02-20 09:05:41
【问题描述】:
Go 的 append() 函数仅在给定切片的容量不足时分配新的切片数据(另请参见:https://stackoverflow.com/a/28143457/802833)。这可能会导致意外行为(至少对于我作为 golang 新手而言):
package main
import (
"fmt"
)
func main() {
a1 := make([][]int, 3)
a2 := make([][]int, 3)
b := [][]int{{1, 1, 1}, {2, 2, 2}, {3, 3, 3}}
common1 := make([]int, 0)
common2 := make([]int, 0, 12) // provide sufficient capacity
common1 = append(common1, []int{10, 20}...)
common2 = append(common2, []int{10, 20}...)
idx := 0
for _, k := range b {
a1[idx] = append(common1, k...) // new slice is allocated
a2[idx] = append(common2, k...) // no allocation
idx++
}
fmt.Println(a1)
fmt.Println(a2) // surprise!!!
}
输出:
[[10 20 1 1 1] [10 20 2 2 2] [10 20 3 3 3]]
[[10 20 3 3 3] [10 20 3 3 3] [10 20 3 3 3]]
https://play.golang.org/p/8PEqFxAsMt
那么,Go 中强制分配新切片数据或更准确地说是确保 append() 的切片参数保持不变的(惯用)方式是什么?
【问题讨论】:
-
“问题”不是附加的行为,而是您的代码不必要的复杂。
-
@Volker 该示例是从更大的上下文中提取的。如果我只需要附加显示的切片,确实有一种更简单的方法:-)