之前在学习C/C++时,我们知道有NULL
在C中NULL是一个(void*)的指针,其定义如下:
#define NULL ((void *)0)
而在C++中,NULL直接可以和0划等号,定义:
/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else /* __cplusplus */
#define NULL ((void *)0)
#endif /* __cplusplus */
#endif /* NULL */
因为C++支持重载,若将NULL继续定义为void*类型,编译器无法判断该调哪个函数,因此限定NULL为0,但是C++中的空指针该怎么办,C++又引入了nullptr来表示空指针,它可以被转换成任意类型的指针类型和bool类型,但是不能转int类型。
NULL不但可以表示0,还能表示 ‘\0’ ,他们几个的值都是一样的,都是0。
今天我们主要来聊聊golang中的nil。
对Golang有所了解的人一定会知道nil,在go代码中,nil简直无处不在。
我们用的最多的可能就是对err的判断,如下:
a , err := math.atoi ( s )
if err != nil {
return err
}
我们常常将err和nil进行比较,当err==nil时,说明未出现错误,而不相等时说明函数出错,需要处理。
这里的nil相当于零值,当我们声明了一个变量,但是未将其初始化,那么系统会自动为他赋一个零值,不同类型的零值分别如下:
int | 0 |
---|---|
bool | false |
string | “” |
pointer | nil |
map | nil |
slice | nil |
channel | nil |
function | nil |
interface | nil |
go文档中,nil是一个预定义的标识符,代表很多类型的zero value,它的定义:
type Type int
var nil Type
看到这里 我们发现这个nil它是一个变量,可以人为改变的
不同类型nil的内存地址始终是相同的 ,都是0x00
- 为nil的slice它的len()和cap() 都是0,通过索引访问时会panic,但是可以使用append进行扩容。
- 对于nil指针,我们不能访问指针指向的值,同样不能调用指针对象的方法,否则会panic,但我们可以通过指针接收器来解决,在函数里面进行判断即可。
- 对于nil的map,我们把它当作一个只读的指针。
- 对于nil的channel,关闭一个nil的channel会导致程序panic。
- interface有一些特殊,它的底层由两部分组成,分别是类型和值,只有当类型和值都为nil时,interface才为nil。