Использование карты для ее установленных свойств с пользовательскими типами - PullRequest
3 голосов
/ 16 января 2011

Я пытаюсь использовать встроенный тип карты в качестве набора для своего собственного типа (в данном случае Point). Проблема в том, что когда я назначаю точку на карту, а затем создаю новую, но равную точку и использую ее в качестве ключа, карта ведет себя так, как будто этого ключа нет на карте. Разве это невозможно сделать?

// maptest.go

package main

import "fmt"

func main() {
    set := make(map[*Point]bool)

    printSet(set)
    set[NewPoint(0, 0)] = true
    printSet(set)
    set[NewPoint(0, 2)] = true
    printSet(set)

    _, ok := set[NewPoint(3, 3)] // not in map
    if !ok {
        fmt.Print("correct error code for non existent element\n")
    } else {
        fmt.Print("incorrect error code for non existent element\n")
    }

    c, ok := set[NewPoint(0, 2)] // another one just like it already in map
    if ok {
        fmt.Print("correct error code for existent element\n") // should get this
    } else {
        fmt.Print("incorrect error code for existent element\n") // get this
    }

    fmt.Printf("c: %t\n", c)
}

func printSet(stuff map[*Point]bool) {
    fmt.Print("Set:\n")
    for k, v := range stuff {
        fmt.Printf("%s: %t\n", k, v)
    }
}

type Point struct {
    row int
    col int
}

func NewPoint(r, c int) *Point {
    return &Point{r, c}
}

func (p *Point) String() string {
    return fmt.Sprintf("{%d, %d}", p.row, p.col)
}

func (p *Point) Eq(o *Point) bool {
    return p.row == o.row && p.col == o.col
}

1 Ответ

2 голосов
/ 17 января 2011
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)

    s := make(map[*Point]bool)
    s[p1] = true
    s[p2] = true
    fmt.Println("s:", s)

    t := make(map[int64]*Point)
t[int64(p1.row)<<32+int64(p1.col)] = p1
t[int64(p2.row)<<32+int64(p2.col)] = p2
    fmt.Println("t:", t)
}

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

Если мы создаем указатели на два Points p1 и p2 с одинаковыми координатами, они указывают на разные адреса.

s := make(map[*Point]bool) создает карту, где ключ является указателемпамяти, выделенной для Point, и значение является логическим значением.Поэтому, если мы присвоим элементам p1 и p2 карте s, у нас будет два различных ключа карты и два различных элемента карты с одинаковыми координатами.

t := make(map[int64]*Point) создает карту, в которойkey является составной частью координат Point, а значение является указателем на координаты Point.Следовательно, если мы присвоим элементам p1 и p2 карте t, то получим два равных ключа карты и один элемент карты с общими координатами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...