【问题标题】:Go: Comparison in maps of interface typesGo:接口类型映射中的比较
【发布时间】:2023-03-28 14:06:01
【问题描述】:

假设我有很多不同的结构类型都满足一个接口Food

type Food interface {
    Name() string
    Tastiness() int
}

type fruit struct {
    species  string
    numSeeds int
}

type vegetable struct {
    commonName string
    weight  int
}

func (f *fruit) Name() string       { return f.species }
func (f *fruit) Tastiness() int     { return 100 - f.numSeeds }
func (v *vegetable) Name() string   { return v.commonName }
func (v *vegetable) Tastiness() int { return 1 }

满足Food 接口的结构使用pointer receivers 的函数来实现,因为我经常传递它们,如果没有指针,这很笨拙。

通常,我想在food1food2 之间进行比较,因此我构建了类似于foodmap := map[Food]bool 的地图。我真正想检查的是底层结构是否相同。但是,因为满足接口的总是指针,所以如果我创建两个相同类型的 fruitvegetable,我就不能使用映射或列表进行相等或存在测试。

是比较Foods 与使用map[Food]bool 而是使用类似map[FoodKey] 的最佳方法,其中满足Food 的任何结构都提供FoodKey() comparisonStruct 方法返回一个严格用于比较的结构?

【问题讨论】:

  • 您能否详细说明“我真正想检查的是底层结构是否相同”?
  • 如果你只有两个Food,你想确保你正在比较两个fruit:类型断言或类型切换(参见规范)。或者:反射。注意:您的问题与指针无关(据我了解您的问题)。第二个注释:“......因为我经常传递它们,没有指针就很笨拙。”在一般情况下是不正确的。传递值非常好,而且通常比指针更快。
  • 也许我不清楚:问题确实与指针有关,因为如果结构(不是指向结构的指针)满足接口,我可以进行相等性检查(指针不成立)。见这里:play.golang.org/p/nWamIr0A6H。我知道这在一般情况下是不正确的,但对我来说是正确的,因为结构很大。

标签: pointers go


【解决方案1】:

比较 Foods 的最佳方法是不使用 map[Food]bool 而是使用类似 map[FoodKey] 的东西,其中任何满足 Food 的结构都提供了一个 FoodKey() comparisonStruct 方法,该方法返回一个严格用于比较的结构?

我怀疑这是一种更好的方法,考虑到:

【讨论】:

    【解决方案2】:

    我相信这里最有效的方法是在你的接口中添加一个额外的函数,比如Is(f Food) bool,它很容易实现,没有使用反射或比较接口或在某处使用映射的开销。

    例子:

    type Food interface {
        Name() string
        Tastiness() int
        Is(f Food) bool
    }
    //....
    func (*fruit) Is(f Food) bool   { _, ok := f.(*fruit); return ok }
    //....
    func (*vegetable) Is(f Food) bool   { _, ok := f.(*vegetable); return ok }
    

    playground

    【讨论】:

      【解决方案3】:

      您有两种选择来确定或比较接口的底层结构。

      1-使用reflect包,具体是reflect.TypeOf函数,它会返回接口的动态类型,如:

      x := Food(fruit{"banana", 0})
      y := Food(vegetable{"potato, 45})
      return reflect.TypeOf(x) == reflect.TypeOf(y)
      

      这段代码会返回false。

      2- 使用类型断言或type switch,例如:

      value, ok := yourInterface.(possibleType)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-03
        • 2021-10-11
        • 1970-01-01
        相关资源
        最近更新 更多