接口作为地图键

时间:2017-08-24 20:40:44

标签: pointers dictionary go

在以下代码中:

package main

import (
  "fmt"
)

type Object interface {
  String() string
}

type Person struct {
  Name string
}

func (p *Person) String() string {
  return fmt.Sprintf("person: %s", p.Name)
}

func main() {
  dict := map[Object]int{
    &Person{Name: "xyz"}: 4,
    &Person{Name: "gle"}: 2,
    &Person{Name: "kp3"}: 7,
  }

  fmt.Println(dict[&Person{Name: "xyz"}])
}

它只打印0,因为地图的键是Objects,它们是接口。我知道为什么会这样,但有什么方法可以解决这个问题吗?我希望能够有一个地图,其键是接口类型,但我仍然可以访问。

的字段

到目前为止,我想到的唯一方法是遍历每个密钥并检查密钥是否与我正在搜索的内容相同,但它可能显着更慢

2 个答案:

答案 0 :(得分:4)

如果在结构而不是指针上定义方法,它确实有效:https://play.golang.org/p/zU4sbFe2RB

如果你不能在实际代码中这样做,我恐怕你无法完成你想要的。这两个指针将是不同的值,即使它们指向相似的数据。

您可以向Equals(Object) bool界面添加Object方法,并推出自己的地图实现。或者,您可以定义Hash() string方法并使用map[string]whatever

答案 1 :(得分:3)

这似乎可能是滥用地图;如果您将地图与对象的String()值相关联(对象的唯一共同点),您可以尝试:

package main

import (
    "fmt"
)

type Object interface {
    String() string
}

type Person struct {
    Name string
}

func (p *Person) String() string {
    return fmt.Sprintf("person: %s", p.Name)
}

func main() {
    xyz := &Person{Name: "xyz"}
    gle := &Person{Name: "gle"}
    kp3 := &Person{Name: "kp3"}
    dict := map[string]int{
        xyz.String(): 4,
        gle.String(): 2,
        kp3.String(): 7,
    }

    fmt.Println(dict[xyz.String()])
}