当前位置 博文首页 > Go中的nil切片和空切片区别详解

    Go中的nil切片和空切片区别详解

    作者:蓝色记忆 时间:2021-04-29 17:44

    Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false。 切片、函数、指针变量的默认为nil。

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

    直接看代码,不同声明方式:使用 make() 函数生成的切片一定发生了内存分配操作,但给定开始与结束位置(包括切片复位)的切片只是将新的切片结构指向已经分配好的内存区域,设定开始与结束位置,不会发生内存分配操作。这里的内存分配我理解的就是引用数组指针地址

    • nil切片和空切片指向的地址不一样。nil空切片引用数组指针地址为0(无指向任何实际地址)
    • 空切片的引用数组指针地址是有的,且固定为一个值

    我们看看切片的数据结构:

    type SliceHeader struct {
     Data uintptr //引用数组指针地址
     Len int   // 切片的目前使用长度
     Cap int   // 切片的容量
    }

    nil切片和空切片最大的区别在于指向的数组引用地址是不一样的。

    所有的空切片指向的数组引用地址都是一样的

     

     示例

     package main
    
    import "fmt"
    
    func main(){
     var a []int
     b:=make([]int,0)
     if a==nil{
     fmt.Println("a is nil")
     }else{
     fmt.Println("a is not nil")
     }
     if b==nil{
     fmt.Println("b is nil")
     }else{
     fmt.Println("b is not nil")
     }
    }

    运行结果:
    a is nil
    b is not nil

    Process finished with exit code 0

    因此:
    通过var a []int创建的切片是一个nil切片
    通过b:=make([]int,0)创建的是一个空切片,(底层数组为空,但底层数组指针非空)

    js
    下一篇:没有了