如何理解golang中的nil
nil的奇怪行为
刚接触golang时,发现nil在不同的上下文,行为表现是不同的,并且和其他语言中的表现,也不大相同
实例1:输入true, true, false,不符合传递性
func main() {
var t *T
var i interface{} = t
fmt.Println(t == nil, i == t, i == nil)
}
实例2:nil可以调用方法
func(t *tree) Sum() int {
if t == nil {
return 0
}
return t.v + t.l.Sum() + t.r.Sum()
}
var t *tree
t.Sum()
理解nil
golang中的nil与其他语言中的语义是一样的,就是代表引用类型的默认值,但是不一样的是,golang中有多种引用类型:pointer、interface、slice、map,channel, function;因此,每种引用类型的默认值,是不一样的,就和基础类型中,bool的默认值是false, int的默认值是0一样
作为一个强类型语言,不同引用类型的判空(nil)规则是不同的;
interface的判空规则是,需要判断类型和值是否都为nil(interface的底层是有类型和值构成的)
slice的判空,需要判断slice引用底层数组的指针为空,容量和size均为0
因此,判断nil的行为时,需要结合nil指向的具体类型,然后做判断;比如实例1中,t是指针,i是interface, i中的数据类型是*T, 值为nil, 但是因为有类型,所有i不为nil; 实例2中,nil指针能够直接调用方法,也是指针的语言特性
总结
理解nil,不能像理解其他语言中的null一样,统一的去看待,需要结合具体的数据类型,然后改数据类型的语言特性去理解;
历史上,null是一个偷懒的设计,虽然理解上很简单,但是导致了许多问题,现代编程语言针对null,都有着自己的改进,比如java中的optional; nil的特性,也体现了golang开发者对null改进的独特思考,由于没有历史包袱,设计可能比较独特,和其他语言差别较大,初上手时可能比较难理解,但是熟悉后,就能感受到其带来的便捷
参考链接
interface{}与nil,违背了==的传递性 - Golang 中国
如何理解golang中的nil的更多相关文章
- [Go] 理解 golang 中的 nil
nil是什么 相信写过Golang的程序员对下面一段代码是非常非常熟悉的了: if err != nil { // do something.... } 当出现不等于nil的时候,说明出现某些错误了, ...
- 理解golang中的channel
channel是goroutine之间的通信机制.可以类比线程间的通信,线程间的通信有多种方式,比如线程上下文.共享内存.IPC通信.socket实现不同机器间的通信. channel用起来很简单,绑 ...
- golang中的nil接收器
索引:https://waterflow.link/articles/1666534616841 我们先看一个简单的例子,我们自定义一个错误,用来把多个错误放在一起输出: type CustomErr ...
- 理解golang中的function types
先找个例子来看一下: package main import "fmt" // Greeting function types type Greeting func(name st ...
- 【荐】详解 golang 中的 interface 和 nil
golang 的 nil 在概念上和其它语言的 null.None.nil.NULL一样,都指代零值或空值.nil 是预先说明的标识符,也即通常意义上的关键字.在 golang 中,nil 只能赋值给 ...
- go---weichart个人对Golang中并发理解
个人觉得goroutine是Go并行设计的核心,goroutine是协程,但比线程占用更少.golang对并发的处理采用了协程的技术.golang的goroutine就是协程的实现. 十几个gorou ...
- Golang中的坑二
Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...
- golang中Context的使用场景
golang中Context的使用场景 context在Go1.7之后就进入标准库中了.它主要的用处如果用一句话来说,是在于控制goroutine的生命周期.当一个计算任务被goroutine承接了之 ...
- 理解Golang哈希表Map的元素
目录 概述 哈希函数 冲突解决 初始化 结构体 字面量 运行时 操作 访问 写入 扩容 删除 总结 在上一节中我们介绍了 数组和切片的实现原理,这一节会介绍 Golang 中的另一个集合元素 - 哈希 ...
随机推荐
- BUAA_OO 第一单元总结
1.简单多项式求导 第一次作业的难点,我认为是对输入的预处理,尤其是正则表达式的使用.这次作业的思路是:首先将表达式进行预处理,(由于题目中要求不会有空格产生的WF,所以可以放心大胆的消除空格). 消 ...
- 使用pthread进行编程
使用pthread进行并行编程 进程与线程 进程是一个运行程序的实例:线程像一个轻量级的进程:在一个共享内存系统中,一个进程可以有多个线程 POSIX® Threads: 即 Pthreads,是一个 ...
- JVM相关参数设置
Java启动参数共分为三类: 其一是标准参数(-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容: 其二是非标准参数(-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足, ...
- python学习20之面向对象编程高级
'''''''''1.动态绑定:对于一个类,我们可以对它的实例动态绑定新的属性或方法.为了使所有的实例均可以使用动态绑定的属性和方法,我们也可以采用对类直接动态绑定'''class Student() ...
- 详解封装源码包成RPM包
源码编译安装是最常用安装软件方式,可是面对工作量巨大时候就需要我们的RPM包上场了,统一的模块,一键安装.在面对一定数量的服务器上,RPM就可以为我们节省大量的时间. RPM可以在网上下载,但是当我们 ...
- Linux系统硬件时间12小时制和24小时制表示设置
目前的服务器status是下面这样的 服务器系统 centos7 Linux系统时间 Fri Mar 20 15:26:27 CST 2020 Linux系统硬件时间 Fri 20 ...
- Docker镜像与仓库(四)
Dockerfile方式创建镜像 https://hub.docker.com/_/centos/ #找一个centos6.6 的dockerfile链接 [root@linux-node1 ~]# ...
- nginx日志、nginx日志切割、静态文件不记录日志和过期时间
2019独角兽企业重金招聘Python工程师标准>>> 12.10 Nginx访问日志 日志格式 vim /usr/local/nginx/conf/nginx.conf //搜索l ...
- 通过express框架为前端提供api(数据),妈妈再也不用担心后端不给我数据了~
个人网站 https://iiter.cn 程序员导航站 开业啦,欢迎各位观众姥爷赏脸参观,如有意见或建议希望能够不吝赐教! 首先,确保自己安装了express框架. 没有安装的同学可以参照下面这篇博 ...
- KNN (K近邻算法) - 识别手写数字
KNN项目实战——手写数字识别 1. 介绍 k近邻法(k-nearest neighbor, k-NN)是1967年由Cover T和Hart P提出的一种基本分类与回归方法.它的工作原理是:存在一个 ...