12_切片长度容量与append
理解切片视图、底层数组共享和追加时的容量变化。
Go 基础专题 12:切片、长度、容量与 append
学习目标:理解切片视图、底层数组共享和追加时的容量变化。
核心知识
切片 []T 是可变长度序列的视图,包含指向底层数组的信息、长度 len 和容量 cap。make([]int, 2, 4) 创建长度 2、容量 4 的切片;s[0:2] 包含起点不含终点。append 返回新的切片值,因此要写 s = append(s, value)。
package main
import "fmt"
func main() {
base := []int{1, 2, 3}
view := base[:2]
view[0] = 9
base = append(base, 4)
fmt.Println(base, view) // [9 2 3 4] [9 2]
}
切片和原切片可能共享底层数组,修改元素会相互可见;append 在容量不足时会分配新数组,所以追加后的共享关系可能变化。不要依赖具体扩容倍数。独立复制元素可用 copy(dst, src),或在合适版本中使用 slices.Clone。
nil 切片的 len 为 0,可直接追加;空但非 nil 的切片也有长度 0,在 JSON 编码等边界可能表现不同。向函数传切片时会复制切片头部,但元素通常共享;函数内 append 后若要让调用者看到新长度,需要返回切片。
逐步理解
画一条底层数组,再画两个切片指向其中不同范围,就能理解为什么改 view[0] 会改变 base[0]。append 返回新的切片头部;容量足够时可能继续共享,容量不足时可能分离。需要稳定独立的数据副本时显式复制,不要根据一次运行的扩容结果推断长期行为。
动手练习
练习:从 []int{1,2,3} 复制出独立切片并修改第一个元素。答案要点:clone := append([]int(nil), original...)。