2

Some of the existing answers on here about how to determine the type of an object at runtime..god help us

if reflect.TypeOf(err) ==  string {

}

that doesn't compile

if reflect.TypeOf(err) ==  "string" {

}

neither does that or this:

if reflect.TypeOf(err).Kind() ==  "string" {

}

how do we do this?

If I use the typeof function given by one of the answers, I get:

enter image description here

  • Read the docs for the package you're using: https://golang.org/pkg/reflect/ `TypeOf` does not return a string, nor does `Kind`. – Adrian Dec 20 '18 at 14:31

2 Answers2

10

Compare like string

if reflect.TypeOf(err).String() == "string" {
    fmt.Println("hello")
}

Or using type assertions

type F = func()

func typeof(v interface{}) string {
    switch v.(type) {
    case int:
        return "int"
    case string:
        return "string"
    case F:
        return "F"
    //... etc
    default:
        return "unknown"
    }
}

Then

var f F
if typeof(f) == "F"{
    fmt.Println("hello F")
}
KibGzr
  • 2,053
  • 14
  • 15
  • 1
    ok thanks, what if it's a custom type though? like if I have `type F = func()`, and I want to see if the TypeOf(err) is F? –  Dec 20 '18 at 03:03
  • 1
    thanks, is there any case where `v.(type)` would fail? –  Dec 20 '18 at 03:13
  • 2
    as I known is none. – KibGzr Dec 20 '18 at 03:15
  • 1
    Totally go for type assertions. most of the times using reflection doesn't make you look smarter. Always use the language provided constructs if you can. This pretty much looks like one of those cases – DallaRosa Dec 20 '18 at 03:23
  • I got some pretty funky stuff when I tried this technique out, guess I will use type assertions –  Dec 20 '18 at 04:34
  • Comparing strings like `reflect.TypeOf(err).String() == "string"` can have false positives because Type.String() is not guaranteed to be unique among all types. – Charlie Tumahai Dec 20 '18 at 14:29
3

To compare types using reflect, compare reflect.Type values:

var stringType = reflect.TypeOf("") // this can be declared at package-level

if reflect.TypeOf(v) == stringType {
    // v has type string
}

Given an arbitrary type name X, you can construct the type using:

var xType = reflect.TypeOf((*X)(nil)).Elem()

if reflect.TypeOf(v) == xType {
    // v has type X
}

If you want to check to see if a value is some type, then use a type assertion:

if _, ok := v.(string); ok {
   // v is a string
}

If you want to map types to strings, use a map keyed by reflect.Type:

var typeName = map[reflect.Type]string{
    reflect.TypeOf((*int)(nil)).Elem():    "int",
    reflect.TypeOf((*string)(nil)).Elem(): "string",
    reflect.TypeOf((*F)(nil)).Elem():      "F",
}

...

if n, ok := typeName[reflect.TypeOf(f)]; ok {
    fmt.Println(n)
} else {
    fmt.Println("other")
}
Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242