golang为什么比较两个指向struct的变量会有不同的行为



我创建了同一结构的两个实例,当我比较两个变量指向结构的实例时,会被输出弄糊涂。

package main
import "fmt"
type Person struct {
name string
}
func main() {
p1 := &Person{name: "guru"}
p2 := &Person{name: "guru"}
fmt.Println(p1 == p2) // false, compares by address?
p3 := Person{name: "guru"}
p4 := Person{name: "guru"}
fmt.Println(p3 == p4) // true , why? compares by content?
}

==运算符的工作方式和重载运算符一样吗?

p1 == p2是指针比较,它比较指针值(内存地址(。由于您使用了2个复合文字(并获取了它们的地址(,它们将指向2个不同的变量,因此地址将不同(因为Person的大小不为零(。规格:复合文字:

获取复合文字的地址会生成一个指针,指向用文字值初始化的唯一变量。

p3 == p4比较结构值,逐字段比较,由于匹配字段的值相等,因此比较将产生true

比较规则在规范中:比较运算符:

相等运算符==和!=适用于可比较的操作数。排序运算符<lt;=>,并且>=适用于排序的操作数。这些术语和比较结果定义如下:

  • […]
  • 指针值是可比较的。如果两个指针值指向同一个变量,或者两个指针的值都为零,则它们是相等的。指向不同零大小变量的指针可能相等,也可能不相等
  • […]
  • 如果结构值的所有字段都是可比较的,则结构值也是可比较的。如果两个结构值对应的非空字段相等,则它们是相等的

您的第一个示例

p1 := &Person{name: "guru"}
p2 := &Person{name: "guru"}
fmt.Println(p1 == p2) // false, compares by address?

比较两个指针是否相等。由于它们各自寻址不同的内存地址,因此比较起来并不相等。

你的第二个例子,

p3 := Person{name: "guru"}
p4 := Person{name: "guru"}
fmt.Println(p3 == p4) // true , why? compares by content?

比较两个结构并按值进行比较,因此它们比较相等。

如果在比较之前取消引用指针,您会发现它们比较起来是相等的。例如,给定

p1 := &Person{ name: "guru" }
p2 := &Person{ name: "guru" }
p3 :=  Person{ name: "guru" }
p4 :=  Person{ name: "guru" }

以下各项比较为相等:

  • *p1 == *p2
  • *p1 == p3
  • p3 == *p2
  • p3 == p4

只有当两个指针在内存中指向同一个值或在Golang中为零时,它们的值才相等。您创建了两个struct实例,因此它们具有不同的地址

p1 := &Person{name: "guru"}
p2 := &Person{name: "guru"}

最新更新