18

I'm quite confused about the .(type) syntax for interface variables. Is it possible to use it like this:

var a,b interface{}
// some code
if first.(type) == second.(type) {
}

or is reflect.TypeOf() the only option to check if the underlying types of a and b are the same type? What comparison am I making in the code above?

user44168
  • 365
  • 1
  • 4
  • 13
  • 3
    *What comparison am I making in the code above?* None, because it doesn't compile. –  Jan 15 '16 at 21:52

4 Answers4

17
func isType(a, b interface{}) bool {
    return fmt.Sprintf("%T", a) == fmt.Sprintf("%T", b)
}

The "%T" fmt option uses reflection under the hood, which would make the above statement practically that same as:

func isType(a, b interface{}) bool {
    return reflect.TypeOf(a) == reflect.TypeOf(b)
}

Either one would work, and won't cause a panic trying to utilize any kind of type assertion like some of the other suggestions.

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
Eric Brown
  • 171
  • 1
  • 3
  • 1
    Using Sprintf could be incorrect. Both of these are not equivalent. Say, if you have 2 pkgs: pkgA/config & pkgB/config. If you compare the type with Sprintf, ie. `config.int == config.int`, they would be equal, which is incorrect. – subtleseeker Dec 13 '22 at 05:17
15

someInterface.(type) is only used in type switches. In fact if you tried to run that you'd see that in the error message.

func main() {
    var a, b interface{}
    a = 1
    b = 1

    fmt.Println(a.(type) == b.(type))
}

prog.go:10: use of .(type) outside type switch

What you could do instead is a.(int) == b.(int), which is really no different from int(a) == int(b)

func main() {
    var a, b interface{}
    a = 1
    b = 1

    fmt.Println(a.(int) == b.(int))
}

true

Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • 14
    Note that the second example will panic if both variables are not of type `int`. – russell_h Aug 23 '16 at 23:27
  • 11
    The question is about comparing types, not about comparing values of the same type. – yaccob Oct 16 '19 at 16:17
  • What does the second code have to do with the question? – Jimmy R.T. Jan 12 '21 at 14:46
  • So the question is "Is it possible to use .(type) like this? ..." and the answer given above is NO. But if you want to do that you can do it like this. Granted the .(int) thing is a little weird, and the panic thing is a problem. But this is the only answer that does answer the question. – demented hedgehog Jan 14 '22 at 03:47
10

You'd need to specify the type. That syntax is used to make type assertions about interfaces, not about checking the specific type. You'll have to use reflect.TypeOf for that.

You can view this answer for a proper use of type assertions.

Community
  • 1
  • 1
jacob
  • 4,656
  • 1
  • 23
  • 32
3

Please try this:

for key, value := range data {
    switch v := value.(type) {
    case string:
        fmt.Println(key, value, "(string)")
    case float64:
        fmt.Println(key, value, "(float64)")
    case []interface{}:
        fmt.Println(key, value, "(interface)")
    }
 }

... and you can use for all types in any interface...

Gabor725
  • 55
  • 1
  • 1