Golang中Slice的一些困惑

Golang中Slice的一些困惑 你好,我是Go语言的初学者。当我开始了解切片时,觉得它非常有趣。

实际上,切片是动态的,并且会引用其底层的原始数组。但是,如果我们声明一个空切片呢?它会引用什么?我对此感到好奇,如果有人知道答案,请分享一下。

func main() {
    var s []int // 这是一个空切片
    fmt.Println(s == nil) // 输出: true
    fmt.Println(len(s))   // 输出: 0
    fmt.Println(cap(s))   // 输出: 0
}
2 回复

一个 nil 切片不会引用任何数组;其底层指针将为 nil。如果你创建一个零大小的切片,其具体行为由实现定义。当前的 Go 编译器会将底层数组指向一个共享的零大小内存位置。

更多关于Golang中Slice的一些困惑的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,空切片确实是一个值得深入理解的概念。当你声明 var s []int 时,会创建一个值为 nil 的切片,它没有底层数组,长度和容量都是0。

package main

import "fmt"

func main() {
    var s1 []int          // nil切片
    s2 := []int{}         // 空切片(非nil)
    s3 := make([]int, 0)  // 空切片(非nil)

    fmt.Printf("s1 == nil: %v, len=%d, cap=%d\n", s1 == nil, len(s1), cap(s1))
    fmt.Printf("s2 == nil: %v, len=%d, cap=%d\n", s2 == nil, len(s2), cap(s2))
    fmt.Printf("s3 == nil: %v, len=%d, cap=%d\n", s3 == nil, len(s3), cap(s3))

    // 所有切片都可以正常追加元素
    s1 = append(s1, 1)
    s2 = append(s2, 2)
    s3 = append(s3, 3)
    
    fmt.Println("s1:", s1) // [1]
    fmt.Println("s2:", s2) // [2]
    fmt.Println("s3:", s3) // [3]
}

关键区别:

  • var s []int 创建的是nil切片,底层数组指针为nil
  • []int{}make([]int, 0) 创建的是非nil的空切片,有分配内存但长度为0

实际使用中,append函数都能正确处理这两种情况,会自动分配底层数组。但如果你需要区分"未初始化"和"空但已初始化"的状态,nil切片就有意义了。

回到顶部