after rereading i think i missed the point of part of your concern.
in this switch it doesn't matter if both are int32 it is already handled before.

>case int, int8, int16, int64:

 you see here that a being int32 is not handled inside it comes in a later case. if its an int type and not int32 we must assume that we need to compare it as a number with b also being handled as a number

>       case int32:
		switch b.(type) {
		case int, int8, int16, int64:
		  return reflect.ValueOf(a).Int() == reflect.ValueOf(b).Int()
		case []byte:
		  return string(a.(int32)) == string(b.([]byte))
		case string:
		  return string(a.(int32)) == b.(string)
		}

here you see that also the type of b governs how a is compared to b

>case int, int8, int16, int64:

here we don't need the int32 case since that would make both equal and would be handled above with both parameters being same type.

now when b is a number we compare them as numbers
if b is a string type compare them casted to string types
although it looks a bit weird it's all pretty factual leaving very little room for unintended behaviour (see the rather comprehensive testing file)