You’ll have to use type assertions and conversions to do this, or find a package where someone else did this already.
Based on your example, I think you could try this:
func Equal(a, b interface{}) bool {
return fmt.Sprint(a) == fmt.Sprint(b)
}
But take a look at the overview of the fmt package. It essentially treats fmt.Sprint(x)
as fmt.Sprintf("%v", x)
and the verb, %v
, means to use a default format to print a value, which based on the table in that overview is:
bool: %t
int, int8 etc.: %d
uint, uint8 etc.: %d, %#x if printed with %#v
float32, complex64, etc: %g
string: %s
chan: %p
pointer: %p
Note how all the ints all get formatted the same. A significant part of the code that does this is here. There still are type assertions and conversions. The difference is that there’s added overhead of building up and representing the values as strings.
A concrete type in Go (i.e. everything that isn’t an interface: int
, string
, []interface{}
, etc.) is not some sort of “tag” that determines what operations are allowed on a value. Among other things, the type also determines:
- How the value is laid out in memory (example).
- When you’re dealing with integers, it doesn’t only deal with the memory layout but also the semantics of basic arithmetic on those integers (example).
In both scenarios, disregarding the type information gets you the wrong answer.
As you can see from fmt.Fprintf
and friends, it’s possible to create a function to handle these kinds of assertions and conversions, but you’ll need to either hard-code how values should be considered equal or not or somehow expose those choices to callers of your Equal
function. The Go language designers decided to leave implicit conversions, (in)equality comparisons, etc. out of the language because there’s ambiguity in how everyone thinks values should be compared equal.