[英]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
函数来执行此操作,因为我经常传递它们,而没有指针则很难。
通常情况下,我想打的比较food1
和food2
,所以我构想了一个看起来像地图foodmap := map[Food]bool
。 我真正要检查的是底层结构是否相同。 但是,由于总是满足该接口的指针,因此,例如,如果我创建两种相同种类的fruit
或vegetable
,则无法使用地图或列表进行相等性或存在性测试。
比较Food
的最佳方法是不使用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.