zoukankan      html  css  js  c++  java
  • golang的可空类型和零值

    non-nillbale and nillable types 可空和不可空类型

    类型可以分为可空类型和不可空类型, 对应的默认值就为 nil 和零值(下方有说明)

    可空类型可以置为nil

    不可空类型不允许置为nil,否则会导致 nil-panic 

     

     

    不可空的基本类型

    在go里面,基本类型都是不可空类型

    var a int = nil

    无法通过编译,因为 int 无法置成0值。 int 的默认值是0。

    var a int // default value of int, cannot be nil
    fmt.Println(a) // 0

    0 我们称之为类型的零值

     

    类型零值表 zero-value 

    Types Zero value
    int, int8, int16, int32, int64 0
    uint, uint8, uint16, uint32, uint64 0
    uintptr 0
    float32, float64 0.0
    byte 0
    rune 0
    string "” (empty string)

    complex64, complex128

    (0,0i)

    boolean

    false

    arrays of non-nillable types array of zero-values
    arrays of nillable types array of nil-values

     

    不可空的结构体

    struct 也是不可空的,它的默认值由字段( field )的默认值组成

     

    可空类型

    可空类型的默认值为  nil 

    需要保持可警惕,是否未nil,在可空类型在被初始化之前使用,可能会导致panic

    可空类型包含:

    • functions 函数
    • channels 管道
    • slices 切片
    • maps 映射
    • interface 接口
    • pointer 指针

     

    空映射 map

    map会返回对应类型的默认值, 不会导致panic 

    但是,对空map赋值会导致panic 

    type Person struct {
        Name string
        Age  int
        Married bool
    }
    
    func main() {
    
        var mp map[string]Person  
        var mpP map[string]*Person
        var mpS map[string]string
        
        //->  map[]
        fmt.Println(mp)
        
        //->  { 0 false} 有一个空字符串
        fmt.Print(mp["me"])
        
        // nil
        fmt.Println(mpP["me"])
        
        // 空字符串
        fmt.Println(mpS[99])
        
        // panic: assignment to entry in nil map
        mpS[1] = "SSS"
    }

    代码链接

     

    为初始化使用导致 panic 

        var mp map[string]int
        //panic: assignment to entry in nil map
        mp["me"] = 0

     

    空切片 slice

    对空切片取值, 仅会导致数组越界的panic 

    但是对,未初始化的slice len() 和 cap() 返回0,  append 操作也可以安全使用

        var s []Person
        
        //[]
        fmt.Println(s)
        
        // 0  0
        fmt.Println(len(s), cap(s))
        
        s = append(s, Person{Name:"kurt", Age: 18, Married:false})
        fmt.Println(s)
        
        //panic: runtime error: index out of range [1] with length 1
        fmt.Println(s[1])

    代码地址

     

    可空类型的panic

    • pointers
    • functions
    • interface-types

    以上类型使用对时候需要保持留意是否为nil值

     

    panic

    • pointers
    var p *int // pointer to an int
    *p++ // panic: runtime error: invalid memory address or nil pointer dereference
    // p is an address to nothing, and therefore is nil
    • interface
    var p error // nil-value of type error
    error.Error() // panic: runtime error: invalid memory address or nil pointer dereference
    • func
    var f func(string) // nil-function
    f("oh oh") // panic: runtime error: invalid memory address or nil pointer dereference

     

    死锁

    • nil的channel无法读或者写,会造成死锁
    var c chan bool
        
    //fatal error: all goroutines are asleep - deadlock!
    c <- true
        
    fmt.Println("hello world")
    • 关闭nil值对channel会导致panic
    var c chan bool
        
    //panic: close of nil channel
    close(c)
        
    fmt.Println("hello world")

     

    以上

    系统地学习go各种类型的默认值

     

    参考文献

    原文地址 https://nilsmagnus.github.io/post/nillability-in-go/ (英文)

    语雀博文 https://www.yuque.com/docs/share/102a846a-013b-49a5-a149-063264a930a0?# 《golang的可空类型和零值》

  • 相关阅读:
    Vue3.0 是如何变得更快的?
    阿里云 Centos7 安装mongodb
    ASP.Net Core5.0 EF Core使用记录
    MongoDB批量更新|按条件更新SQL|批量删除某个字段
    Layui单元格编辑获取修改前的值
    判断字符串出现的多个位置
    原生JavaScript的DOM操作汇总
    @Value值为null、#和$的区别
    Dubbo推荐用法
    Dubbo 服务化最佳实践
  • 原文地址:https://www.cnblogs.com/Gilfoyle/p/14259725.html
Copyright © 2011-2022 走看看