golang 不同类型的nil值

golang 不同类型的nil值

nil通道

var ch chan int

通道必须使用make函数进行初始化,对nil管道进行读写会导致永久阻塞

nil切片

package main

import "fmt"

func main() {
    var s1 []int
    if s1 == nil {
        fmt.Println("sl is nil")
    }

    var s2 = []int{}
    if s2 != nil {
        fmt.Println("s2 is not nil")
    }

    fmt.Println("nil slice len: ", len(s1))
    for range s1 {

    }

    s1 = append(s1, 1)
}
sl is nil
s2 is not nil
nil slice len:  0

在go语言中空切片和nil在比较时是不一样的,在遍历、获取长度、添加元素时是一样的

为什么要区分空切片和nil切片?

var status *bool

在实际CRUD业务中的修改操作实际上需要提供PUTPATCH两种接口,即全量修改和增量修改;

比如对于status状态字段,就会有:修改为true、修改为false、不修改三种状态,如果不使用指针的话是无法区分这三种状态的(当然也可以通过在批量、全量添加业务代码强行判断)

切片也是类似的,常见的区别就是在json序列化时空切片和nil切片是有区别的

nil映射

package main

import "fmt"

func main() {
    var s1 map[int]bool
    if s1 == nil {
        fmt.Println("sl is nil")
    }

    fmt.Println("nil slice len: ", len(s1))
    for range s1 {

    }

    s1[1] = true
}
sl is nil
nil slice len:  0
panic: assignment to entry in nil map

nil切片有所类似,nil映射在获取长度、遍历时是一样的,不需要特殊区分;

但是nil映射,是不能直接赋值的会报错

为什么nil映射不能兼容?

nil切片可以兼容是因为新创建的切片会通过返回值返回出去,而map是不行的

nil接口

package main

import "fmt"

type myError struct {
}

func (m *myError) Error() string {
    return ""
}

func main() {
    var me *myError
    if me == nil {
        fmt.Println("成功")
    } else {
        fmt.Println("错误")
    }

    var e error = me
    if e == nil {
        fmt.Println("成功")
    } else {
        fmt.Println("错误")
    }
}
成功
错误

nil赋值给某个interface和将某种类型的nil指针赋值给interface是不一样的,这里面有两个原因:

  • 哪怕是nil指针也是可以调用到此类型的方法的
  • nil不包含任何方法在interface底层会使用eface存储、空指针在interface底层会使用iface存储、同时会存储其相关的方法

你可能感兴趣的:(golang 不同类型的nil值)