Go:接口类型的映射比较

时间:2014-08-07 10:47:03

标签: pointers go

假设我有很多不同的结构类型,它们都满足接口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。我真正想要检查的是底层结构是否相同。但是,因为它始终是满足界面的指针,所以如果我创建两个相同类型的fruit或{{1},我就无法使用地图或列表进行相等或存在测试例如。

是将vegetable进行比较的最佳方法使用Food,而是使用类似map[Food]bool的内容,其中任何结构均为{{1}提供了一个map[FoodKey]方法,它返回一个严格意义上用于比较的结构?

3 个答案:

答案 0 :(得分:1)

  

比较Foods是不使用map[Food]bool的最好方法,而是使用map[FoodKey]之类的东西,其中任何符合条件的结构提供了一个FoodKey() comparisonStruct方法,该方法返回一个严格意义上的结构比较

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

答案 1 :(得分:1)

我认为这里最有效的方法是为你的界面增加一个额外的功能,如Is(f Food) bool,它易于实现,没有使用反射或比较接口或在某处使用地图的开销。 / p>

示例:

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

答案 2 :(得分:0)

您有两种方法可以确定或比较接口的基础结构。

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)