电话
400 9058 355
Go中指针相等仅取决于是否指向同一内存地址或同为nil;==比较不关心值、内容或结构体字段,不同类型指针不可比较,零大小结构体指针可能因地址复用而意外相等。
Go 中两个指针相等,只看它们是否指向**同一块内存地址**,或是否都为 nil;值相同、结构体内容一样、甚至都是 &struct{}{},都不保证指针相等。
Go 允许直接用 == 或 != 比较同类型指针,但结果完全取决于底层地址是否一致:
p1 == p2 为 true 当且仅当 p1 和 p2 存储的是同一个地址(比如都指向变量 a),或两者都是 nil
*p1 == *p2 成立(值相等),p1 == p2 仍可能为 false —— 它们只是“长得像”,不是“同一个人”*int 和 *int64)无法直接比较,编译报错:mismatched types *int and *int64
func main() {
a, b := 42, 42
p1 := &a
p2 := &b
fmt.Println(p1 == p2) // false —— 不同变量,不同地址
fmt.Println(*p1 == *p2) // true —— 值相同,但和指针比较无关
}
对结构体指针使用 ==,比的是指针本身,不是它指向的字段。想比内容,必须解引用:
p1 == p2:只在 p1 和 p2 是同一个结构体实例的地址时才为 true
*p1 == *p2:要求结构体所有字段可比较(不能含 []int、map[string]int 或函数),否则编译失败data *string),*p1 == *p2 仍只比指针地址,不比 *data 的值type User struct {
Name string
Age int
}
u1 := &User{"Alice", 30}
u2 := &User{"Alice", 30}
fmt.Println(u1 == u2) // false
fmt.Println(*u1 == *u2) // true —— 字段都可比较,且值相同
这是最容易踩坑的冷知识:指向 struct{} 这类零大小变量的指针,在接口中比较时可能“意外相等”,哪怕它们来自不同调用:
&struct{}{} 多次调用返回的指针地址相同interface{},one == two 可能返回 true,但你根本没创建同一个对象byte 字段或注释字段即可)type fake struct{ _ [0]byte } // 非零大小,强制分配独立地址
// 而不是 type fake struct{} —— 危险!
函数名本身不可比较:someFunc == someFunc 编译失败,报错 func can only be compared to nil:
f == nil
reflect.ValueOf(f).Pointer()
import "reflect"
func foo() {}
func bar() {}
fmt.Println(reflect.ValueOf(foo).Pointer() == reflect.ValueOf(foo).Pointer()) // true
fmt.Println(refl
ect.ValueOf(foo).Pointer() == reflect.ValueOf(bar).Pointer()) // false
真正难的不是写对 ==,而是意识到你在比什么——地址?值?语义唯一性?一旦把 == 当成“逻辑相等”用,尤其混入接口、零大小类型或函数,就很容易被 Go 的底层行为反向教育。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...