不同的指针是平等的?

时间:2014-09-08 23:18:00

标签: pointers go

我试图将2d平面上的某些点表示为整数对。我希望这些点是不可变的(按值传递),但每个点都有一个唯一的标识。为了实现这一点,我创建了一个包含两个int和一个*string的结构。这很好用:

package main
import "fmt"
func main() {
    s1 := ""
    s2 := ""
    p := Point{1,2,&s1}
    p2 := Point{1,2,&s2}
    fmt.Println(p2==p) // want false
}
type Point struct{X int; Y int; id *string}

$ go run a.go
false

由于string实际上并没有用于任何事情(我只关心两点是否相同),看起来像这样制作一个独特参考的规范解决方案就是使用指向struct{}的指针:

package main
import "fmt"
func main() {
    s1 := struct{}{}
    s2 := struct{}{}
    p := Point{1,2,&s1}
    p2 := Point{1,2,&s2}
    fmt.Println(p2==p) // want false
}
type Point struct{X int; Y int; id *struct{}}

但是,现在两个指针是相同的:

$ go run a.go
true

为什么呢?这也可以用字符串发生吗?我应该使用UUID吗?

2 个答案:

答案 0 :(得分:7)

空结构struct{}{}很特别。

请参阅:http://golang.org/ref/spec#Size_and_alignment_guarantees,其中包含:

  

如果结构或数组类型不包含任何字段(或   元素,分别),大小大于零。二   不同的零大小变量在内存中可能具有相同的地址。

你可以在那里放一个字段来获得唯一性。类似的东西:

package main

import "fmt"

type token struct{ bool }
type Point struct {
    X  int
    Y  int
    id *token
}

func main() {
    p := Point{1, 2, &token{}}
    p2 := Point{1, 2, &token{}}
    fmt.Println(p2 == p) // want false
}

答案 1 :(得分:2)

要区分两个不同的点,即使它们具有相同的坐标,也要使用地址。例如,

package main

import "fmt"

type Point struct {
    X int
    Y int
    p *Point
}

func NewPoint(x, y int) Point {
    p := Point{X: x, Y: y}
    p.p = &p
    return p
}

func main() {
    x, y := 1, 2
    p1 := NewPoint(x, y)
    p2 := NewPoint(x, y)
    fmt.Println(p1)
    fmt.Println(p2)
    fmt.Println(p1 == p1)
    fmt.Println(p1 == p2)
}

输出:

{1 2 0x10328000}
{1 2 0x10328020}
true
false