Golang 指针nil问题、结构体判空 踩坑-1

背景 1

有两个方法A 、B 以及一个结构体 P , AB中传递的是P的指针

 

问题1  代码如下

Golang 指针nil问题、结构体判空 踩坑-1

此代码看着没有明显报错,当你编译的时候不会报错,能打包,但是你运行的时候会报错,

panic: runtime error: invalid memory address or nil pointer dereference , 提示是个空指针。

 

分析

为什么会这样呢,我们首先是初始化了一个结构体指针p,此时它的值是nil,但是我们并没有进行数据存储操作,所以p的指向不变,仍然是nil, 我们要取一个地址为nil的结构体的属性,怎么能取到呢?这个只是简单的例子,业务代码中可能比这个复杂的多,如果函数间用指针传递,在获取返回指针的时候,切记要判断一下返回值是不是nil , 不然你跑起代码后光给你个空指针,你从那找问题?

Golang 指针nil问题、结构体判空 踩坑-1

背景2 

函数间我用值拷贝传递,如果我在B中对结构体做了操作,我想在main方法里判断这个结构体是否有数据,即判断一个结构体是否为结构体空值,我该怎么做呢?

 

问题2 代码如下

Golang 指针nil问题、结构体判空 踩坑-1

分析:

如上代码会打印什么呢?  答案是空字符串,因为函数间用的值拷贝传递,那么实际上返回的结构体已经不是传入的了,而是一个拷贝,拷贝也代表着做过初始化,会默认给结构体属性赋空值,那么如果我想判断返回的结构体是不是结构体空值呢?我们可以再声明一个结构体空值与期待的结构体比较,比如下面这样

Golang 指针nil问题、结构体判空 踩坑-1

这里要注意的一点就是,对照组即重新声明的结构体空值,一定要加个(),不然会引发报错,编译器层面就不会让你过,这样我们就可以比较结构体是否是空值了,这种比较方式只能比较值类型的结构体,指针是不允许比较的哈。

 

ps:  这种比较方式确实可以判断结构体空值,但是也需要付出代价,我们在声明一个结构体的时候会开辟出这个结构体的内存,也是占地方的,虽然很小,函数结束后也会释放,这里是想告诉大家是有损耗的,而只定义一个空struct{}, 是不占内存的,这点可以各位自行查找相关知识学习,这点当个拓展知识吧。所以我们如果有更好的判断方式,你不妨教我一下,感谢