Go指针零值强制为nil,是语言规范定义的确定值;解引用前必须检查nil,否则必panic;nil仅适用于六类引用类型,不可用于基本类型比较。

Go指针的零值就是nil,不是“可能为”,是语言规范强制定义的确定值
所有未显式初始化的指针变量,比如 var p *int 或结构体中未赋值的指针字段,其值**必定是 nil**——这不是编译器猜测,也不是运行时行为,而是 Go 语言规范(Spec)白纸黑字写死的零值规则。它和 0、false、"" 一样,是类型系统的一部分,但只属于六类引用类型:*T、[]T、map[K]V、chan T、func()、interface{}。
解引用前不判 nil,必 panic:这是唯一不可妥协的底线
对 nil 指针执行 * 解引用(如 *p)或访问字段(如 s.name),会立刻触发 panic: invalid memory address or nil pointer dereference。这个 panic 不可恢复,也不看上下文。
- ✅ 安全做法:在任何解引用前手动检查
p != nil,尤其在函数入口、方法体内、结构体嵌套访问时 - ❌ 危险误区:以为“没传参就跳过逻辑”“反正后面不会走到那里”,结果上线后某个分支触发 panic
- ⚠️ 特别注意:
json.Unmarshal、database/sql扫描、HTTP 请求解析等场景常返回*T类型,必须先判空再用
nil 指针调用方法不一定 panic,但风险藏在细节里
一个 nil 指针可以安全调用指针接收者方法——前提是方法内部**没访问接收者字段或解引用自身**。这容易让人误以为“nil 很安全”,实则非常危险。
- ✅
func (s *Student) GetName() string { if s == nil { return "unknown" }; return s.name }—— 显式判空,安全 - ❌
func (s *Student) GetAge() int { return s.age }—— 直接访问字段,s为nil时 panic - ? 值接收者方法(
func (s Student))永远不会因nilpanic,但传入的是零值副本,字段仍是零值(如0、""),不是“空”而是“有默认值”
别把 nil 当成通用“空判断”,它不适用于所有类型
nil 只能和六类引用类型比较;对 int、string、struct 等类型写 v == nil,编译直接报错:invalid operation: v == nil (mismatched types ... and nil)。
立即学习“go语言免费学习笔记(深入)”;
- ✅ 正确判断:切片是否为空用
len(s) == 0,字符串是否为空用s == "",指针是否未初始化用p == nil - ❌ 错误混用:写
if name == nil(name是string)—— 编译失败 - ⚠️ 接口陷阱:
var i interface{} = (*int)(nil),此时i != nil(因动态类型存在),但i的底层值是nil;只有var i interface{}才是真正nil










