Pointers 为什么这些golang指针不相等?
在下面的示例中,我检查两个指针的相等性Pointers 为什么这些golang指针不相等?,pointers,go,Pointers,Go,在下面的示例中,我检查两个指针的相等性 指针指向同一地址 它们不是同一个指针 如何检查两个指针是否指向同一地址?我不想检查两个指针的内容是否相等 package main import ( "fmt" ) type Map struct {} type Fragment struct { Map *Map } func (m1 Map) NewFragment() (f Fragment) { f.Map = &m1 return } var
- 指针指向同一地址
- 它们不是同一个指针
package main
import (
"fmt"
)
type Map struct {}
type Fragment struct {
Map *Map
}
func (m1 Map) NewFragment() (f Fragment) {
f.Map = &m1
return
}
var m Map = Map {}
func main() {
f := m.NewFragment()
fmt.Println(f.Map == &m) // false
fmt.Println(*f.Map == m) // true
}
正如JimB所回答的,您可以使用
==
来比较指针。此程序以这种方式运行的原因是,当您调用NewFragment
方法时,会生成接收器的副本。在这种情况下,这意味着行f.Map=&m1
获取的是副本的地址,而不是原始对象的地址。因此,指针是不同的(f.Map!=&m
),值是相同的(*f.Map==m
)。指针比较
相等运算符==和!=应用于可比较的操作数。
指针值是可比较的。如果两个指针值指向同一个变量或都有值nil,则两个指针值相等
这是一个有效的代码:
func main() {
s := struct{}{}
p1 := &s
p2 := &s
fmt.Println(p1 == p2)
fmt.Printf("%p, %p", p1, p2)
}
指针接收器
您的代码有一个重大错误,它实际上导致了您描述的行为。方法可以用值receiverfunc(s SomeObj)DoSomething(){}
和指针receiverfunc(s*SomeObj)DoSomething(){}
声明。如果使用值接收器声明一个方法(像您那样),您将获得对象的副本,但是如果使用指针接收器声明一个方法(像您应该做的那样),您将获得指向对象本身的指针
您的代码只缺少一个星号:
type Map struct{}
type Fragment struct {
Map *Map
}
func (m1 *Map) NewFragment() (f Fragment) { // Note, this is a pointer receiver
f.Map = m1
return
}
var m Map = Map{}
func main() {
f := m.NewFragment()
fmt.Println(f.Map == &m) // true
fmt.Println(*f.Map == m) // true
fmt.Printf("%p, %p", f.Map, &m)
}
结论
指针比较是检查它是否是相同的指针(标识)。所以,如果你仔细看看你的代码,你会发现你的代码和我上面的例子有着相同的含义
游乐场:
在代码中,func(m1 Map)NewFragment对值而不是指针进行操作。如果将其更改为func(m1*Map)NewFragment()等,则两个Println都将返回true。我不确定您希望该程序在其他情况下如何工作。请使用
==
。如果指针指向同一个变量,则它们具有相同的地址。根据规范:指针值是可比较的。如果两个指针值指向同一个变量或都有值nil,则两个指针值相等。