假设我有很多不同的结构类型,它们都满足接口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
或{{1},我就无法使用地图或列表进行相等或存在测试例如。
是将vegetable
与进行比较的最佳方法使用Food
,而是使用类似map[Food]bool
的内容,其中任何结构均为{{1}提供了一个map[FoodKey]
方法,它返回一个严格意义上用于比较的结构?
答案 0 :(得分:1)
比较Foods是不使用
map[Food]bool
的最好方法,而是使用map[FoodKey]
之类的东西,其中任何符合条件的结构提供了一个FoodKey() comparisonStruct
方法,该方法返回一个严格意义上的结构比较
我怀疑这是一种更好的方法,考虑到:
Equaler
(如this thread所示)并不容易答案 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 }
答案 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)