2011-01-16 13 views
3

自分のタイプ(この場合はPoint)のセットとして組み込みマップタイプを使用しようとしています。問題は、ポイントをマップに割り当て、後に新しいポイントを作成してキーとして使用すると、そのキーがマップにないかのようにマップが動作することです。これはできないのですか?Go - ユーザー定義型で設定したプロパティのマップを使用する

// 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 
} 

答えて

2
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] 

我々は、彼らが別のアドレスを指して同じ座標で2 Pointsp1p2へのポインタを作成した場合。

s := make(map[*Point]bool)は、キーがPointに割り当てられたメモリへのポインタで、値がブール値であるマップを作成します。したがって、p1p2という要素をマップsに割り当てると、2つの異なるマップキーと、同じ座標を持つ2つの異なるマップ要素があります。

t := make(map[int64]*Point)は、キーがPointの座標のコンポジットであり、値がPoint座標へのポインタであるマップを作成します。したがって、p1p2という要素をマップtに割り当てると、2つの等しいマップキーと1つのマップ要素が共有座標で表示されます。

+1

代わりに 'map [int] map [int] Point'があります。メモリ消費量とアクセス時間が増加しましたが、アイテムを見つけやすくなりました。 –

+0

まさに私が言うつもりだった。 – crazy2be

+0

はい。 'map [int] map [int] Point'とPointの特定のインスタンスへのポインタではなく、Point座標の値に依存するマップキーの他のスキームも機能します。 – peterSO

関連する問題