Go中指针、切片、映射、通道、函数和接口可能为nil,使用前须显式判断:指针解引用、映射写入、通道收发/关闭、函数调用、接口方法调用等操作前未判空将panic。
在 Go 语言中,nil 是一个预声明的零值标识符,用于表示指针、切片、映射、通道、函数和接口等类型的“空值”。但直接对 nil 指针解引用(如 *p)或调用 nil 接口/方法(如 obj.Method()),会触发 panic,导致程序崩溃。因此,显式判断 nil 是防御性编程的关键一步。
Go 中只有以下类型可以是 nil,且在使用前建议检查:
invalid memory address or nil pointer dereference
[]int{})行为一致,但语义不同,必要时需区分var w io.Writer = nil 是 nil,而 var buf bytes.Buffer; w = &buf 不是 nil —— 判断接口是否为 nil 要看其底层值是否为 nil核心原则:在解引用、调用、写入、关闭等危险操作前,加一层显式 nil 判断。
if p != nil { val := *p }
if m == nil { m = make(map[string]int) } 或直接 if m != nil { m["key"] = 1 }
if ch != nil { select { case ;发送前同理
if fn != nil { fn() }
if x, ok := obj.(fmt.Stringer); ok && x != nil { s := x.String() };更常见的是设计 API 时要求调用方保证非 nil,或在方法内首行加 if obj == nil { return }
结构体字段若是指针类型(如 *User),其本身可能为 nil,访问其字段会 panic:
u.Profile.Name(若 u.Profile == nil)if u.Profile != nil { name := u.Profile.Name }
func (u *User) ProfileName() string { if u.Profile != nil { return u.Profile.Name }; return "" }
单靠人工容易遗漏,可借助以下方式降低风险:
go vet 检查明显未判空的解引用(部分情况)-race 检测并发下的竞态,有时 nil 访问源于未同步初始化// user must not be nil

nil *Config 看是否 panic 或返回合理错误