nil切片(var s []int)长度容量均为0且底层指针为nil,适合append或json输出null;空切片[]int{}长度容量为0但底层数组非nil,json输出[];二者均不可索引访问。

声明空切片但不分配底层数组
直接使用 var 声明未初始化的切片,会得到一个 nil 切片,长度和容量都是 0,且底层指针为 nil:
var s []int
这种写法适合后续用 append 动态增长,或明确需要与 nil 切片做逻辑区分(比如 JSON 编码时 nil 切片输出为 null,而 [] 输出为 [])。
- 不能对
nil切片做索引访问(如s[0]),会 panic:"index out of range" -
len(s)和cap(s)都返回 0,行为上等价于[]int{},但底层指针不同 - 函数参数接收
[]T类型时,传入nil是完全合法的
用字面量声明非空切片
最常见也最直观的方式是用切片字面量,Go 会自动推导类型并分配底层数组:
s := []string{"a", "b", "c"}
此时 s 是一个长度为 3、容量为 3 的切片,底层数组已分配。注意这里没有指定数组长度(不像 [3]string),所以是切片而非数组。
- 如果想复用已有数组,可用
arr[low:high]形式切出子切片,例如:arr := [5]int{1,2,3,4,5}; s := arr[1:4] - 字面量声明的切片,其底层数组生命周期由 Go 自动管理,无需手动释放
- 不要误写成
[]int{1,2,3}后面加;或换行导致语法错误——Go 对分号插入有规则,但字面量后紧跟换行通常没问题
用 make 创建指定长度和容量的切片
当需要预分配空间、避免多次扩容时,用 make 最合适:
s := make([]int, 3) // len=3, cap=3<br>s := make([]int, 3, 10) // len=3, cap=10
make 返回的是切片头(slice header),不是指针;它分配的底层数组元素会被零值初始化(int 是 0,*int 是 nil)。
- 第二个参数是
len,必须 ≥ 0;第三个参数(可选)是cap,必须 ≥len,否则 panic:"len larger than cap" - 如果只给两个参数,
cap默认等于len;若需预留扩容空间,显式指定第三个参数更安全 - 对性能敏感场景(如循环中反复追加),提前设好足够
cap可减少内存重分配次数
类型别名声明切片类型再实例化
当多个变量共享同一结构(比如都表示“用户ID列表”),可先定义类型再声明变量,提升可读性和一致性:
type UserIDList []int<br>var ids UserIDList = []int{101, 102, 103}
这不会创建新类型(UserIDList 仍可直接赋值给 []int),只是类型别名,适用于文档化意图或封装方法。
- 如果后续要为该类型添加方法,必须用
type UserIDList []int这种方式定义(不能用type UserIDList = []int) - 别名类型变量仍支持所有原生切片操作(
append、切片、len等) - 注意别名只是语法糖,不影响运行时行为或内存布局
最容易被忽略的是 nil 切片和空切片([]T{})在反射、JSON 序列化、通道发送等场景下的行为差异——它们都满足 len() == 0,但底层指针是否为 nil 会影响某些库的判断逻辑。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











