nil 切片
var s []int // nil 切片
特点:
- 未初始化的切片就是 nil 切片
- 长度和容量都是 0
- 底层指针为 nil
- 可以直接和 nil 比较:
s == nil返回 true
空切片
s := []int{} // 空切片
s := make([]int, 0) // 空切片
特点:
- 长度和容量都是 0
- 底层指针指向一个内存地址(不是 nil)
- 和 nil 比较会返回 false:
s == nil返回 false
零切片
s := make([]int, 3) // 零切片
特点:
- 切片长度不为 0
- 底层数组的元素都是对应类型的零值
- 示例中的切片元素都是 0
他们的主要区别:
// nil 切片
var s1 []int
fmt.Printf("len=%d cap=%d pointer=%p\n", len(s1), cap(s1), &s1)
fmt.Println(s1 == nil) // true
// 空切片
s2 := []int{}
fmt.Printf("len=%d cap=%d pointer=%p\n", len(s2), cap(s2), &s2)
fmt.Println(s2 == nil) // false
// 零切片
s3 := make([]int, 3)
fmt.Printf("len=%d cap=%d pointer=%p\n", len(s3), cap(s3), &s3)
fmt.Println(s3) // [0 0 0]
使用建议:
- 声明切片时,一般用 nil 切片即可
- 在需要即时分配内存时,可以使用空切片
- 当你需要一个指定长度,且元素都为零值的切片时,使用零切片
需要注意的是:nil 切片和空切片的行为基本是一致的,它们都可以直接使用 append,都可以正常迭代。主要区别在于它们的内部实现和与 nil 的比较结果。