Go语言中的零切片、空切片、和nil切片的区别

237 阅读1分钟

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]

使用建议:

  1. 声明切片时,一般用 nil 切片即可
  2. 在需要即时分配内存时,可以使用空切片
  3. 当你需要一个指定长度,且元素都为零值的切片时,使用零切片

需要注意的是:nil 切片和空切片的行为基本是一致的,它们都可以直接使用 append,都可以正常迭代。主要区别在于它们的内部实现和与 nil 的比较结果。