参考:

有趣的面试题:Go语言中的nil比较 - 知乎 (zhihu.com)

理解Go语言的nil - 简书 (jianshu.com)

Golang中的nil,没有人比我更懂nil! - 知乎 (zhihu.com)

常用的nil

在写程序的时候经常会遇到nil这个词,比如说错误判断:

f, err := os.Open(filePath)
if err != nil {panic(err)
}

这很容易理解,但是有如果对nilnil进行比较,如下:

fmt.Println(nil== nil)

我第一反应是true,但是能作为面试题,肯定不会那么简单。显然是我太菜了,那么今天就来扒一扒nil

nil的官方定义

查看Golang的官方定义builtin - The Go Programming Language (golang.org):

nil is a predeclared identifier representing the zero value for a pointer, channel, func, interface, map, or slice type.

var nil Type // Type must be a pointer, channel, func, interface, map, or slice type

翻译之后,总结起来,nil是:

  • 一个标识符(并不是关键字)
  • 预先定义零值
  • 针对
    • pointer
    • channel
    • func
    • interface
    • map
    • slice

nil是一个标识符

nil不是一个关键字,只是一个标识符。这就说明你可以自己定义一个变量去覆盖它。

这是可以编译通过的,但是不建议那么做。

nil有类型吗

从定义可知,nil是多个类型的零值,这些类型之间的差别很大,那么nil怎么能表示这些零值,而且nil有类型吗?

我尝试将nil赋值给变量a并打印出来,会显示use of untyped nil;

也就是说,nil是没有默认类型的,使用nil的时候必需提供充足的上下文信息来让编译器推断其类型。

使用nil比较

nil与nil进行比较

回归上面的面试题,对nil和nil进行比较,结果如下:

编译没有通过,显示的错误为操作==在nil中没有定义==符号对于nil来说是一种未定义的操作,所以不可以来比较两个nil

不同类型的nil比较

不同类型之间的nil进行比较,结果如何呢?

可以看到,不同类型之间的nil是无法进行比较的,显示为mismatched types

各种类型的零值与地址

那么,不同类型的零值实际上是什么?我们尝试来打印各种类型nil的实际GO语法表示地址

总结起来如下:

类型 值的Go语法表示 address
map map[int]string(nil) 0x0
pointer (*int) (*int)(nil) 0x0
channel (chan int)(nil) 0x0
slice []int(nil) 0x0
func (func())nil 0x0
interface <nil> %!p(<nil>)

可以看到大部分地址都是相同的,每种类型nil的实际表示并不是一致的,所以不同类型nil不能进行比较。

总结

总的来说,nil值一个针对map等类型预先定义的零值的标识符。由于不是关键字,所以写代码中要注意不要使用nil作为变量名。nil的类型是不定的,会根据具体的定义环境而发生改变,这就要求我们在对nil进行比较时要特别注意。

理解Golang中的nil相关推荐

  1. golang中的nil

    golang中的nil与其他语言中的语义是一样的,就是代表引用类型的默认值,但是不一样的是, golang中有多种引用类型:pointer.interface.slice.map,channel, f ...

  2. 理解golang中什么是nil

    nil是什么 // nil is a predeclared identifier representing the zero value for a // pointer, channel, fun ...

  3. 深入理解Golang中的Context包

    context.Context是Go语言中独特的设计,在其他编程语言中我们很少见到类似的概念.context.Context深度支持Golang的高并发. 1. Goroutine和Channel 在 ...

  4. 理解Golang中defer的使用

    之前一直对Go中的defer不太理解,所以我单独弄出来整理一下. 在golang当中,defer代码块会在函数调用链表中增加一个函数调用.这个函数调用不是普通的函数调用,而是会在函数正常返回,也就是r ...

  5. golang 切片 接口_如何理解Golang中的接口?

    个人认为,要理解 Go 的接口,一定先了解下鸭子模型. 鸭子模型 那什么鸭子模型? 鸭子模型的解释,通常会用了一个非常有趣的例子,一个东西究竟是不是鸭子,取决于它的能力.游泳起来像鸭子.叫起来也像鸭子 ...

  6. go每日新闻(2021-02-05)——Golang 中 nil==nil 是对是错?

    每日一谚: Go对OO提供了另类的支持:有方法(method)无类(class),有接口(interface)但无类型体系,代码可重用,但不通过继承的方式. go中文网每日资讯–2021-02-05 ...

  7. golang中string不能为nil

    golang中不能用nil初始化string package mainfunc main() {var s strings = nil } 运行报错:cannot use nil as type st ...

  8. Golang中闭包的理解

    简介 参考博客: https://www.calhoun.io/what-is-a-closure/ https://blog.cloudflare.com/a-go-gotcha-when-clos ...

  9. Golang中的自动伸缩和自防御设计

    Raygun服务由许多活动组件构成,每个组件用于特定的任务.其中一个模块是用Golang编写的,负责对iOS崩溃报告进行处理.简而言之,它接受本机iOS崩溃报告,查找相关的dSYM文件,并生成开发者可 ...

最新文章

  1. python爬虫一般格式
  2. Linux学习(八)---crond 任务调度
  3. ajax只能用get吗,基本的Ajax,但无法使用GET或POST方法
  4. 携手长江天成转型 谋定·农业大健康-林裕豪:升级山茶油农产品
  5. redis 判断存在性_实战 | springboot+redis+拦截器 实现接口幂等性校验
  6. SAP智能机器人流程自动化解决方案
  7. 单机版简易考试系统开发过程讲解(C#注册机、用户注册、考试系统、×××全部源码)...
  8. 爬虫-12-发送带参数的请求
  9. python嵌套类(内部类相互调用)_核心解密Python函数在(类与函数之间)和(类与类之间)互相调用...
  10. android循环请求数据,android – Camera2 ImageReader冻结重复捕获请求
  11. python怎么读是什么意思-python中的PEP是什么?怎么理解?(转)
  12. Idea 格式化代码 Idea设置快捷键 格式化代码
  13. python实现算法改进_运动目标检测vibe算法及其改进Python实现
  14. OSI常用网络协议(七层)
  15. 620集成显卡和mx250,轻薄本的新独显!MX250现身英伟达官网,核显3.5倍性能
  16. pow是什么意思python,python中pow什么意思
  17. SAP菜单中添加事务操作实例
  18. 今日说“法”:如何防止reg、wire型信号在使用逻辑分析仪时被优化
  19. leveldb安装以及使用
  20. java rgb十六进制数据转图片

热门文章

  1. 如何撩学计算机的小哥哥,女生撩小哥哥的套路情话 我其实是个不好亲近的人...
  2. Python3全栈之面向对象基础
  3. 趣图:我全部重构好啦!
  4. 趣图:等等,我还没备份呢
  5. web标准中的网页:结构层、表现层、行为层
  6. 计算机视觉 单应性 Homography
  7. 验证码识别服务器,一个非常好用的验证码识别工具类api接口
  8. Web网页技术学习心得
  9. 程序猿媛:滑动翻页+区域点击事件
  10. matlabI 配置成vsCODE风格的暗色主题