【问题标题】:Interfaces as map keys接口作为映射键
【发布时间】:2018-02-02 20:40:50
【问题描述】:

在以下代码中:

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,它们是接口。我知道为什么会发生这种情况,但是有什么办法可以解决吗?我希望能够拥有一个其键是接口类型的映射,但我仍然可以访问它的字段。

到目前为止我想到的唯一方法是遍历每个键并检查该键是否等于我正在搜索的内容,但它可能会明显慢.

【问题讨论】:

  • 这看起来像是一个可能的XY Problem - 你实际上想要完成什么?映射键应该通常只是键,如果您需要从它们到您想要的接口类型的行为,您可能需要考虑不同的方法。
  • 我的键是接口类型的原因是因为我正在制作一种程序可以制作地图的语言,其中键 值都是相同的类型:对象。
  • 这并不意味着解释器应该使用 Go maps 来实现该语言的映射。
  • 没错,但实现我自己的地图类型似乎需要付出很多努力。
  • 写一个语言解释器requires a lot of effort.

标签: pointers dictionary go


【解决方案1】:

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

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

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

【讨论】:

  • 我可能只是实现我自己的地图。
【解决方案2】:

这似乎是对地图的滥用;如果您要从对象的 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()])
}

【讨论】:

  • 好主意,但我必须更改很多代码才能使其正常工作。
猜你喜欢
  • 2021-10-11
  • 2013-05-13
  • 2021-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
相关资源
最近更新 更多