使用地图来存储具有用户定义类型的集合属性

huangapple go评论119阅读模式
英文:

Using a map for its set properties with user defined types

问题

我试图使用内置的map类型作为我自己的类型(在这种情况下是Point)的集合。问题是,当我将一个Point赋值给map,并且稍后创建一个新的但相等的point并将其用作键时,map的行为就好像该键不在map中一样。这样做是不可能的吗?

  1. // maptest.go
  2. package main
  3. import "fmt"
  4. func main() {
  5. set := make(map[*Point]bool)
  6. printSet(set)
  7. set[NewPoint(0, 0)] = true
  8. printSet(set)
  9. set[NewPoint(0, 2)] = true
  10. printSet(set)
  11. _, ok := set[NewPoint(3, 3)] // not in map
  12. if !ok {
  13. fmt.Print("correct error code for non existent element\n")
  14. } else {
  15. fmt.Print("incorrect error code for non existent element\n")
  16. }
  17. c, ok := set[NewPoint(0, 2)] // another one just like it already in map
  18. if ok {
  19. fmt.Print("correct error code for existent element\n") // should get this
  20. } else {
  21. fmt.Print("incorrect error code for existent element\n") // get this
  22. }
  23. fmt.Printf("c: %t\n", c)
  24. }
  25. func printSet(stuff map[*Point]bool) {
  26. fmt.Print("Set:\n")
  27. for k, v := range stuff {
  28. fmt.Printf("%s: %t\n", k, v)
  29. }
  30. }
  31. type Point struct {
  32. row int
  33. col int
  34. }
  35. func NewPoint(r, c int) *Point {
  36. return &Point{r, c}
  37. }
  38. func (p *Point) String() string {
  39. return fmt.Sprintf("{%d, %d}", p.row, p.col)
  40. }
  41. func (p *Point) Eq(o *Point) bool {
  42. return p.row == o.row && p.col == o.col
  43. }
英文:

I'm trying to use the built-in map type as a set for a type of my own (Point, in this case). The problem is, when I assign a Point to the map, and then later create a new, but equal point and use it as a key, the map behaves as though that key is not in the map. Is this not possible to do?

  1. // maptest.go
  2. package main
  3. import "fmt"
  4. func main() {
  5. set := make(map[*Point]bool)
  6. printSet(set)
  7. set[NewPoint(0, 0)] = true
  8. printSet(set)
  9. set[NewPoint(0, 2)] = true
  10. printSet(set)
  11. _, ok := set[NewPoint(3, 3)] // not in map
  12. if !ok {
  13. fmt.Print("correct error code for non existent element\n")
  14. } else {
  15. fmt.Print("incorrect error code for non existent element\n")
  16. }
  17. c, ok := set[NewPoint(0, 2)] // another one just like it already in map
  18. if ok {
  19. fmt.Print("correct error code for existent element\n") // should get this
  20. } else {
  21. fmt.Print("incorrect error code for existent element\n") // get this
  22. }
  23. fmt.Printf("c: %t\n", c)
  24. }
  25. func printSet(stuff map[*Point]bool) {
  26. fmt.Print("Set:\n")
  27. for k, v := range stuff {
  28. fmt.Printf("%s: %t\n", k, v)
  29. }
  30. }
  31. type Point struct {
  32. row int
  33. col int
  34. }
  35. func NewPoint(r, c int) *Point {
  36. return &Point{r, c}
  37. }
  38. func (p *Point) String() string {
  39. return fmt.Sprintf("{%d, %d}", p.row, p.col)
  40. }
  41. func (p *Point) Eq(o *Point) bool {
  42. return p.row == o.row && p.col == o.col
  43. }

答案1

得分: 3

package main

import "fmt"

type Point struct {
row int
col int
}

func main() {
p1 := &Point{1, 2}
p2 := &Point{1, 2}
fmt.Printf("p1: %p %v p2: %p %v\n", p1, *p1, p2, *p2)

  1. s := make(map[*Point]bool)
  2. s[p1] = true
  3. s[p2] = true
  4. fmt.Println("s:", s)
  5. t := make(map[int64]*Point)
  6. t[int64(p1.row)<<32+int64(p1.col)] = p1
  7. t[int64(p2.row)<<32+int64(p2.col)] = p2
  8. fmt.Println("t:", t)

}

Output:
p1: 0x7fc1def5e040 {1 2} p2: 0x7fc1def5e0f8 {1 2}
s: map[0x7fc1def5e0f8:true 0x7fc1def5e040:true]
t: map[4294967298:0x7fc1def5e0f8]

如果我们创建指向具有相同坐标的两个Point p1p2的指针,它们指向不同的地址。

s := make(map[*Point]bool) 创建一个映射,其中键是指向分配给Point的内存的指针,值是布尔值。因此,如果我们将元素p1p2分配给映射s,那么我们就有了两个不同的映射键和两个具有相同坐标的映射元素。

t := make(map[int64]*Point) 创建一个映射,其中键是Point的坐标的组合,值是指向Point坐标的指针。因此,如果我们将元素p1p2分配给映射t,那么我们就有了两个相等的映射键和一个具有共享坐标的映射元素。

英文:
  1. package main
  2. import &quot;fmt&quot;
  3. type Point struct {
  4. row int
  5. col int
  6. }
  7. func main() {
  8. p1 := &amp;Point{1, 2}
  9. p2 := &amp;Point{1, 2}
  10. fmt.Printf(&quot;p1: %p %v p2: %p %v\n&quot;, p1, *p1, p2, *p2)
  11. s := make(map[*Point]bool)
  12. s[p1] = true
  13. s[p2] = true
  14. fmt.Println(&quot;s:&quot;, s)
  15. t := make(map[int64]*Point)
  16. t[int64(p1.row)&lt;&lt;32+int64(p1.col)] = p1
  17. t[int64(p2.row)&lt;&lt;32+int64(p2.col)] = p2
  18. fmt.Println(&quot;t:&quot;, t)
  19. }
  20. Output:
  21. p1: 0x7fc1def5e040 {1 2} p2: 0x7fc1def5e0f8 {1 2}
  22. s: map[0x7fc1def5e0f8:true 0x7fc1def5e040:true]
  23. t: map[4294967298:0x7fc1def5e0f8]

If we create pointers to two Points p1 and p2 with the same coordinates they point to different addresses.

s := make(map[*Point]bool) creates a map where the key is a pointer to the memory allocated to a Point and the value is boolean value. Therefore, if we assign elements p1 and p2 to the map s then we have two distinct map keys and two distinct map elements with the same coordinates.

t := make(map[int64]*Point) creates a map where the key is a composite of the coordinates of a Point and the value is a pointer to the Point coordinates. Therefore, if we assign elements p1 and p2 to the map t then we have two equal map keys and one map element with the shared coordinates.

huangapple
  • 本文由 发表于 2011年1月17日 04:18:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/4707790.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定