3 回答
TA贡献1828条经验 获得超3个赞
您将切片、数据类型与实际表示混淆了。切片描述符由一对 int 组成,一个用于 len,一个用于 cap,以及一个指向底层数据的指针。
因此, append 返回的确实是一个新切片,而传递给 add 选项的确实是切片描述符的副本。但是由于描述符有一个指向数据的指针,所以指针值(指向底层数据的地址)是相同的。
编辑:这是一个代码片段来说明我的观点:
package main
import "fmt"
func main() {
s := make([]int, 0, 5)
s = append(s, []int{1, 2, 3, 4}...)
a := append(s, 5)
fmt.Println(a)
b := append(s, 6)
fmt.Println(b)
fmt.Println(a)
}
如果你运行这个,你会得到:
[1 2 3 4 5]
[1 2 3 4 6]
[1 2 3 4 6]
因为既然s仍然有能力,都a和b共享相同的数据PTR。如果将容量更改为 4,则会打印:
[1 2 3 4 5]
[1 2 3 4 6]
[1 2 3 4 5]
TA贡献1827条经验 获得超9个赞
当append()创建一个新切片时,它不会创建一个只比之前的切片大一个的切片。它实际上创建了一个比前一个大几个元素的切片。看看这个代码:
package main
import "fmt"
func main() {
var sl []bool
for i := 0; i < 100; i++ {
sl = append(sl, true)
fmt.Println(cap(sl))
}
}
Playground
如果您运行此代码,您会看到容量最初在每次分配时翻倍;对于更大的切片大小,这个策略当然会改变。
- 3 回答
- 0 关注
- 268 浏览
添加回答
举报