• 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!!!
  • 相关阅读:
    情报收集:Metasploit命令、查询网站和测试网站
    Hbase 学习笔记5----hbase region, store, storefile和列簇的关系
    Hbase 学习笔记4----原理
    Hbase 学习笔记3----操作以及维护
    Hbase 学习笔记2----概念
    Hbase 学习笔记1----shell
    Flume日志收集 总结
    Hadoop应用开发实战案例 第2周 Web日志分析项目 张丹
    2016.4.9-关于“放生”反而促进“捕猎”的思考
    Hadoop应用开发实战案例 第1周 基本介绍
  • 原文地址:https://www.cnblogs.com/JunkingBoy/p/15196621.html
Copyright © 2020-2023  润新知