2 回答
TA贡献1773条经验 获得超3个赞
切片只是数组一部分的窗口,它没有特定的存储空间。
这意味着如果在数组的同一部分有两个切片,则两个切片必须“包含”相同的值。
这正是这里发生的事情:
当您执行第一个操作时
append
,您将在一个大小2
为基础的数组上获得一个新的大小切片2
。当您执行 next 时
append
,您将获得一个新的大小切片,3
但底层数组的大小4
(append
通常分配的空间比立即需要的空间多,因此不需要在每次追加时分配)。这意味着 next
append
不需要新数组。因此x
,y
两者都将使用与先例 slice 相同的底层数组s
。你写11
然后12
在这个数组的同一个槽中,即使你得到两个不同的切片(记住,它们只是窗口)。
您可以通过在每次 append 后打印切片的容量来检查:
fmt.Println(cap(s))
如果你想在x
and 中有不同的值y
,你应该做一个副本,例如这样:
s := []int{5}
s = append(s, 7)
s = append(s, 9)
x := make([]int,len(s))
copy(x,s)
x = append(x, 11)
y := append(s, 12)
fmt.Println(s, x, y)
这里的另一个解决方案可能是强制s切片后面的数组的容量不大于所需的容量(从而确保以下两个append 必须使用新数组):
s := []int{5}
s = append(s, 7)
s = append(s, 9)
s = s[0:len(s):len(s)]
x := append(s, 11)
y := append(s, 12)
fmt.Println(s, x, y)
TA贡献1876条经验 获得超5个赞
dystroy 很好地解释了它。我喜欢为行为添加视觉解释。
切片只是数组段的描述符。它由指向数组的指针 (ptr)、段的长度 (len) 和容量 (cap) 组成。
+-----+
| ptr |
|*Elem|
+-----+
| len |
|int |
+-----+
| cap |
|int |
+-----+
所以,代码的解释如下;
func main() {
+
|
s := []int{5} | s -> +-----+
| []int | ptr +-----> +---+
| |*int | [1]int| 5 |
| +-----+ +---+
| |len=1|
| |int |
| +-----+
| |cap=1|
| |int |
| +-----+
|
s = append(s,7) | s -> +-----+
| []int | ptr +-----> +---+---+
| |*int | [2]int| 5 | 7 |
| +-----+ +---+---+
| |len=2|
| |int |
| +-----+
| |cap=2|
| |int |
| +-----+
|
s = append(s,9) | s -> +-----+
| []int | ptr +-----> +---+---+---+---+
| |*int | [4]int| 5 | 7 | 9 | |
| +-----+ +---+---+---+---+
| |len=3|
| |int |
| +-----+
| |cap=4|
| |int |
| +-----+
|
x := append(s,11) | +-------------+-----> +---+---+---+---+
| | | [4]int| 5 | 7 | 9 |11 |
| | | +---+---+---+---+
| s -> +--+--+ x -> +--+--+
| []int | ptr | []int | ptr |
| |*int | |*int |
| +-----+ +-----+
| |len=3| |len=4|
| |int | |int |
| +-----+ +-----+
| |cap=4| |cap=4|
| |int | |int |
| +-----+ +-----+
|
y := append(s,12) | +-----> +---+---+---+---+
| | [4]int| 5 | 7 | 9 |12 |
| | +---+---+---+---+
| |
| +-------------+-------------+
| | | |
| s -> +--+--+ x -> +--+--+ y -> +--+--+
| []int | ptr | []int | ptr | []int | ptr |
| |*int | |*int | |*int |
| +-----+ +-----+ +-----+
| |len=3| |len=4| |len=4|
| |int | |int | |int |
| +-----+ +-----+ +-----+
| |cap=4| |cap=4| |cap=4|
| |int | |int | |int |
+ +-----+ +-----+ +-----+
fmt.Println(s,x,y)
}
- 2 回答
- 0 关注
- 193 浏览
添加回答
举报