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)
}
指针接收器 您的代码有一个重大错误,它实际上导致了您描述的行为。方法可以用值receiver
func(s SomeObj)DoSomething(){}
和指针receiver
func(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,则两个指针值相等。