Reputation: 1349
I want to compare my type by the specific way. For this purpose, I create the function MyType.Same(other MyType) bool
for each type.
In some generic function, I want to check if the parameter has a function "Same" and invoke it if yes.
How can I do it in a generic way for different types?
type MyType struct {
MyField string
Id string // ignored by comparison
}
func (mt MyType) Same(other MyType) bool {
return mt.MyField == other.MyField
}
// MyOtherType... Same(other MyOtherType)
type Comparator interface {
Same(Camparator) bool // or Same(interface{}) bool
}
myType = new(MyType)
_, ok := reflect.ValueOf(myType).Interface().(Comparator) // ok - false
myOtherType = new(myOtherType)
_, ok := reflect.ValueOf(myOtherType).Interface().(Comparator) // ok - false
Upvotes: 3
Views: 5703
Reputation: 120951
The types do not satisfy the Comparator
interface. The types have a Same
method, but those methods do not have argument type Comparator
. The argument types must match to satisfy an interface.
Change the the methods and interface to take the same argument type. Use a type assertion to check that receiver and argument have the same type and to get argument as the receiver's type.
type Comparator interface {
Same(interface{}) bool
}
func (mt MyType) Same(other interface{}) bool {
mtOther, ok := other.(MyType)
if !ok {
return false
}
return return mt.MyField == mtOther.MyField
}
Use the following to compare two values:
func same(a, b interface{}) bool {
c, ok := a.(Comparator)
if !ok {
return false
}
return c.Same(b)
}
If the types the application works with have the Compare
method, then there's no need to declare the Comparator
interface or use the same
function in the previous snippet of code. For example, the Comparator
interface is not required for the following:
var mt MyType
var other interface{}
eq := mt.Same(other)
Upvotes: 7