指针比较只看地址不看值,== 判断是否指向同一内存地址;不同类型指针不可直接比较;nil 必须显式判断;零大小结构体指针比较结果不确定。

指针比较只看地址,不看值
在 Go 中,== 比较两个指针,判断的是它们是否指向**同一块内存地址**,而不是所指向的值是否相等。这是最常被误解的一点。
- 即使
p1和p2都指向值为42的变量,只要地址不同,p1 == p2就是false - 结构体指针也一样:
p1 == p2为true仅当它们是同一个变量的地址(比如p2 = p1) - 想比内容?必须解引用:
*p1 == *p2—— 但前提是结构体字段都可比较(不能含slice、map或函数)
不同类型指针不能直接比较
Go 是强类型语言,*int 和 *int64 即使底层都是 8 字节,也不能用 == 直接比较,编译器会报错:mismatched types *int and *int64。
- 错误写法:
var x int = 10 var y int64 = 10 px := &x py := &y // fmt.Println(px == py) // 编译失败
- 如确需跨类型比地址(极少见),须统一转为
unsafe.Pointer:unsafe.Pointer(px) == unsafe.Pointer(py) - 但这种转换绕过类型系统,易引发隐患,应避免用于业务逻辑,仅限底层工具或 FFI 场景
nil 指针判断必须显式写 == nil
未初始化的指针默认值是 nil,但 Go 不允许隐式布尔转换,也不能用 if p 这类写法。
- 正确判断空指针:
var p *int if p == nil { fmt.Println("指针为空") } - 解引用前务必检查:
if p != nil { fmt.Println(*p) },否则运行时 panic - 方法接收者为指针时,
nil调用会 panic(除非方法内主动判空),建议在入口加if p == nil { return }
零大小结构体的指针比较行为特殊
对于空结构体 struct{} 或只含零大小字段的类型,多个不同变量的指针在比较时可能意外相等 —— 这是 Go 规范允许的实现细节,不是 bug。
立即学习“go语言免费学习笔记(深入)”;
- 例如:
var a, b struct{} pa, pb := &a, &b fmt.Println(pa == pb) // 可能 true,也可能 false,不可依赖 - 这意味着:不能靠
==判断两个零大小变量是否“不同”,也不能用它做唯一性标识 - 若需稳定区分,应使用
reflect.ValueOf(p).Pointer()获取绝对地址,或改用带字段的结构体
nil 处理和零大小类型这三处最容易漏掉细节。尤其在写通用工具或封装接口时,别假设指针相等意味着值相等,也别把跨类型比较当成理所当然。










