Compare two variables regardless of their data type

Hi,

I am trying to compare only the value of a variable regardless of its data type.

I don’t want to do the typical “switch case” where I make the assertion for each type that exists.

Is it possible to do this? compare 2 variables regardless of their data type?

package main

import (
	"fmt"
	"reflect"
)

func main() {
	var a interface{} = int64(2)
	var b string = "2"
	fmt.Println("its false:", a == b)	
	
	reflectValueA:= reflect.ValueOf(a)
	reflectValueB:= reflect.ValueOf(b)
	fmt.Println(reflectValueA, reflectValueB)	
	fmt.Println("its ?:", reflectValueA == reflectValueB)		
}

https://play.golang.org/p/UBO9G7YNACW

Thanks everyone for your help.

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.

1 Like

@skillian

I hadn’t looked at him from that point.

Thanks for your answer and thanks for showing me another point of view to find the solution.