Go切片必须基于数组或已有切片创建,常用make(控制长度/容量)或字面量(初始化已知元素);支持截取生成共享底层数组的视图;需警惕nil/空切片差异、append扩容机制及底层数组生命周期问题。
Go语言中切片不能直接“创建”而必须基于底层数组(或已有切片)生成,最安全、最常用的方式是用 make 或字面量初始化。
make 创建带长度和容量的切片这是控制内存分配最明确的方式,适用于需要预分配空间、避免频繁扩容的场景(比如批量读取文件、网络缓冲)。
make([]T, len):创建长度为 len、容量也为 len 的切片,所有元素为零值make([]T, len, cap):创建长度 len、容量 cap(cap >= len)的切片,超出 len 的部分不可访问但可被 append 复用len > cap,编译报错:len larger than cap in 
make([]T)
append 性能:只要不超容,append 是 O(1);一旦触发扩容(通常翻倍),会分配新底层数组并拷贝,开销变大示例:
buf := make([]byte, 0, 1024) // 预留1KB容量,初始长度0,适合循环append
适合已知初始元素的场景,简洁直观,底层自动调用 make 并赋值。
[]int{1, 2, 3}:长度和容量都为 3[]string{"a", "b"}:类型由元素推导,无需显式写 []string(但在函数参数或变量声明中常需)[]int{} 和 var s []int 效果一致:长度 0、容量 0、底层数组为 nil
[3]int{1,2,3} 是数组,不是切片;少一个 [] 就完全不是同一类型这是切片“视图”特性的核心用法,不分配新底层数组(除非后续 append 触发扩容),共享内存。
arr[1:3]:从数组 arr 截取,新切片长度 = 3-1,容量 = len(arr)-1
s[2:4:6]:三索引切片,显式指定新容量(上限为原容量减起始偏移),防止意外覆盖原数据s[10:] 当 len(s)==5)会 panic,运行时检查很多问题源于混淆“零值切片”“nil 切片”和“空切片”,以及对底层数组生命周期的误判。
var s []int、s = nil、s = []int{} 三者 len/cap 都是 0,但前两者 s == nil 为 true,最后一个为 false;json.Marshal 对 nil 切片输出 null,对空切片输出 []
append 到同一个切片,却未重置(如 s = s[:0]),会导致旧数据残留[]T 参数时,内部 append 可能扩容并返回新底层数组,但调用方变量未更新——必须显式接收返回值:s = append(s, x)
range 遍历切片时,迭代变量是副本,修改它不影响原切片;要改元素得用索引:s[i] = ...
底层数组的生命周期只取决于是否有活跃的切片引用它——哪怕原始变量早已离开作用域,只要还有切片指向它,就不会被回收。这点和 C 的指针不同,也和 Java 的引用不同,容易在长期运行服务中引发意料外的内存驻留。