• 8.28Go之容器之nil


    8.28Go之容器之nil

    nil的特点

    • 是Go语言中一个预定义好的标识符

    • 是"指针、切片、映射、通道、函数、接口的零值"

    nil与null不同点

    nil标识符是不能比较的

    ==对于 nil 来说是一种未定义的操作

    package main

    import "fmt"

    func main() {
    fmt.Println(nil == nil)
    }
    /*
    会提示
    # command-line-arguments
    .NilPractice.go:6:18: invalid operation: nil == nil (operator == not defined on nil)
    */

    nil不是关键字或保留字

    可以定义一个名为nil的变量

    package main

    import "fmt"

    func main() {
       nil := "Hello"
       fmt.println(nil)
       /*这在Go语言中是合法的*/
    }

    nil没有默认类型

    package main

    import "fmt"

    func main() {
    fmt.Printf("%T", nil)
    print(nil)
    }

    不同类型nil的指针是一样的

    package main

    import "fmt"

    func main() {
    /*声明两个变量*/
    var arr []int
    var num *int

    /*分别利用格式化输出他们的nil值*/
    fmt.Printf("%p ", arr)
    fmt.Printf("%p", num)
    /*
    fmt.Printf方法返回一个整数类型的值
    和常规的空值验证
    */
    }
    //arr 和 num 的指针都是 0x0

    指针指向的内存地址不一样:

    package main

    import "fmt"

    func main() {
    /*声明两个变量*/
    var arr []int
    var num *int

    /*分别利用格式化输出他们的nil值*/
    fmt.Printf("%p ", &arr)
    fmt.Printf("%p", &num)
    /*
    fmt.Printf方法返回一个整数类型的值
    和常规的空值验证
    */
    }
    //这两个的结果是不一样的

    不同类型的nil值不能比较

    package main

    import "fmt"

    func main() {
    /*声明两个变量*/
    var mapValue map [int] string
    var ptr *int

    fmt.Printf(mapValue == ptr)
    }
    /*
    这会导致编译无法通过
    */

    两个相同类型的nil值也可能无法比较

    map、slice 和 function 类型的 nil 值不能比较。会导致编译不通过

    package main

    import "fmt"

    func main() {
       /*声明两个切片*/
       var num1 []int
       var num2 []int
       
       fmt.Printf(num1 == num2)
       fmt.Printf(num1 == nil) //这也会导致编译无法通过--->不能将空值直接与nil标识符进行比较
    }

    nil 是 map、slice、func、pointer、channel、interface 的零值

    package main
    import (
       "fmt"
    )
    func main() {
       var m map[int]string
       var ptr *int
       var c chan int
       var sl []int
       var f func()
       var i interface{}
       fmt.Printf("%#v ", m)
       fmt.Printf("%#v ", ptr)
       fmt.Printf("%#v ", c)
       fmt.Printf("%#v ", sl)
       fmt.Printf("%#v ", f)
       fmt.Printf("%#v ", i)
    }

    不同类型的nil值占用的内存大小可能是不一样的

    • 一个类型的所有的值的内存布局都是一样的,nil 的大小与同类型中的非 nil 类型的大小是一样的。

    • 不同类型的 nil 值的大小可能不同。

    package main
    import (
       "fmt"
       "unsafe"
    )
    func main() {
       var p *struct{}
       fmt.Println( unsafe.Sizeof( p ) ) // 8
       var s []int
       fmt.Println( unsafe.Sizeof( s ) ) // 24
       var m map[int]bool
       fmt.Println( unsafe.Sizeof( m ) ) // 8
       var c chan string
       fmt.Println( unsafe.Sizeof( c ) ) // 8
       var f func()
       fmt.Println( unsafe.Sizeof( f ) ) // 8
       var i interface{}
       fmt.Println( unsafe.Sizeof( i ) ) // 16
    }

    总结

    • nil不是Go语言当中预先定义好的标识符或保留字,可以作为变量名

    • 不同类型的nil无法比较,相同类型的nil有可能也无法比较

    • nil是引用类型的零值,map、slice、function的nil值无法比较--->其他的引用类型是可以的

    It's a lonely road!!!
  • 相关阅读:
    [备忘]使用Outlook 2010,拖拽大于20M附件发生“附件大小超过了允许的范围”提示的解决方法
    关于Linq to SQL 的“异常详细信息: System.InvalidCastException: 指定的转换无效。”
    [备忘]ie6中href设为javascript:void(0)页面无法提交的解决方法
    [备忘]谷歌员工证实PR值不再更新 呼吁用户关注内容
    今天早上
    C++primer6.20
    Fuzzy KNN
    数值转换
    ArcMap分割图斑
    VS2008 集成openCV过程
  • 原文地址:https://www.cnblogs.com/JunkingBoy/p/15196621.html
Copyright © 2020-2023  润新知