理解Golang中的nil
参考:
有趣的面试题: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)
}
这很容易理解,但是有如果对nil
与nil
进行比较,如下:
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相关推荐
- golang中的nil
golang中的nil与其他语言中的语义是一样的,就是代表引用类型的默认值,但是不一样的是, golang中有多种引用类型:pointer.interface.slice.map,channel, f ...
- 理解golang中什么是nil
nil是什么 // nil is a predeclared identifier representing the zero value for a // pointer, channel, fun ...
- 深入理解Golang中的Context包
context.Context是Go语言中独特的设计,在其他编程语言中我们很少见到类似的概念.context.Context深度支持Golang的高并发. 1. Goroutine和Channel 在 ...
- 理解Golang中defer的使用
之前一直对Go中的defer不太理解,所以我单独弄出来整理一下. 在golang当中,defer代码块会在函数调用链表中增加一个函数调用.这个函数调用不是普通的函数调用,而是会在函数正常返回,也就是r ...
- golang 切片 接口_如何理解Golang中的接口?
个人认为,要理解 Go 的接口,一定先了解下鸭子模型. 鸭子模型 那什么鸭子模型? 鸭子模型的解释,通常会用了一个非常有趣的例子,一个东西究竟是不是鸭子,取决于它的能力.游泳起来像鸭子.叫起来也像鸭子 ...
- go每日新闻(2021-02-05)——Golang 中 nil==nil 是对是错?
每日一谚: Go对OO提供了另类的支持:有方法(method)无类(class),有接口(interface)但无类型体系,代码可重用,但不通过继承的方式. go中文网每日资讯–2021-02-05 ...
- golang中string不能为nil
golang中不能用nil初始化string package mainfunc main() {var s strings = nil } 运行报错:cannot use nil as type st ...
- Golang中闭包的理解
简介 参考博客: https://www.calhoun.io/what-is-a-closure/ https://blog.cloudflare.com/a-go-gotcha-when-clos ...
- Golang中的自动伸缩和自防御设计
Raygun服务由许多活动组件构成,每个组件用于特定的任务.其中一个模块是用Golang编写的,负责对iOS崩溃报告进行处理.简而言之,它接受本机iOS崩溃报告,查找相关的dSYM文件,并生成开发者可 ...
最新文章
- python爬虫一般格式
- Linux学习(八)---crond 任务调度
- ajax只能用get吗,基本的Ajax,但无法使用GET或POST方法
- 携手长江天成转型 谋定·农业大健康-林裕豪:升级山茶油农产品
- redis 判断存在性_实战 | springboot+redis+拦截器 实现接口幂等性校验
- SAP智能机器人流程自动化解决方案
- 单机版简易考试系统开发过程讲解(C#注册机、用户注册、考试系统、×××全部源码)...
- 爬虫-12-发送带参数的请求
- python嵌套类(内部类相互调用)_核心解密Python函数在(类与函数之间)和(类与类之间)互相调用...
- android循环请求数据,android – Camera2 ImageReader冻结重复捕获请求
- python怎么读是什么意思-python中的PEP是什么?怎么理解?(转)
- Idea 格式化代码 Idea设置快捷键 格式化代码
- python实现算法改进_运动目标检测vibe算法及其改进Python实现
- OSI常用网络协议(七层)
- 620集成显卡和mx250,轻薄本的新独显!MX250现身英伟达官网,核显3.5倍性能
- pow是什么意思python,python中pow什么意思
- SAP菜单中添加事务操作实例
- 今日说“法”:如何防止reg、wire型信号在使用逻辑分析仪时被优化
- leveldb安装以及使用
- java rgb十六进制数据转图片