繁体   English   中英

前往:界面类型映射中的比较

[英]Go: Comparison in maps of interface types

假设我有很多不同的结构类型,它们都满足一个接口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 ,则无法使用地图或列表进行相等性或存在性测试。

比较Food的最佳方法是使用map[Food]bool而不是使用map[FoodKey] ,在该方法中,任何满足Food结构都将提供FoodKey() comparisonStruct方法,该方法返回严格用于比较的结构?

比较Foods的最佳方法是不使用map[Food]bool而是使用诸如map[FoodKey] ,在该方法中,任何满足Food的结构都将提供FoodKey() comparisonStruct方法,该方法返回严格用于比较的结构?

考虑到以下因素,我怀疑这是更好的方法:

我相信这里最有效的途径是为您的界面添加一个额外的功能,例如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 }

操场

您有两个选择来确定或比较接口的基础结构。

1-使用reflect包,特别是reflect.TypeOf函数,它将返回接口的动态类型,例如:

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

这段代码将返回false。

2-使用类型断言或类型开关 ,例如:

value, ok := yourInterface.(possibleType)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM