557

How do I find the type of an object in Go? In Python, I just use typeof to fetch the type of object. Similarly in Go, is there a way to implement the same ?

Here is the container from which I am iterating:

for e := dlist.Front(); e != nil; e = e.Next() {
    lines := e.Value
    fmt.Printf(reflect.TypeOf(lines))
}

I am not able to get the type of the object lines in this case which is an array of strings.

golopot
  • 10,726
  • 6
  • 37
  • 51
Rahul
  • 11,129
  • 17
  • 63
  • 76

16 Answers16

667

The Go reflection package has methods for inspecting the type of variables.

The following snippet will print out the reflection type of a string, integer and float.

package main

import (
    "fmt"
    "reflect"
)

func main() {

    tst := "string"
    tst2 := 10
    tst3 := 1.2

    fmt.Println(reflect.TypeOf(tst))
    fmt.Println(reflect.TypeOf(tst2))
    fmt.Println(reflect.TypeOf(tst3))

}

Output:

string
int
float64

see: http://play.golang.org/p/XQMcUVsOja to view it in action.

More documentation here: http://golang.org/pkg/reflect/#Type

Ziaur Rahman
  • 1,148
  • 11
  • 24
dethtron5000
  • 10,363
  • 1
  • 31
  • 32
  • reflect aint working for me. I have updated the question. I have included code snippet in this case. – Rahul Nov 24 '13 at 04:08
580

I found 3 ways to return a variable's type at runtime:

Using string formatting

func typeof(v interface{}) string {
    return fmt.Sprintf("%T", v)
}

Using reflect package

func typeof(v interface{}) string {
    return reflect.TypeOf(v).String()
}

Using type switch

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

Every method has a different best use case:

  • string formatting - short and low footprint (not necessary to import reflect package)

  • reflect package - when need more details about the type we have access to the full reflection capabilities

  • type switch - allows grouping types, for example recognize all int32, int64, uint32, uint64 types as "int"

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Grzegorz Luczywo
  • 9,962
  • 1
  • 33
  • 22
  • 4
    It seems that you can get rid of variable `t`, so `t := v.(type)` becomes `v.(type)`, and `_ = t` is no longer needed. – Akavall Feb 28 '17 at 06:21
  • 4
    Based on a barebones benchmark, the reflect approach is surprisingly more efficient https://gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e – Mike Rapadas Apr 06 '17 at 20:53
  • 1
    `case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String())`. fmt package using reflect to print type – Fantasy_RQG Feb 03 '20 at 03:40
  • 3
    Note that `v.(type)` only works in `switch` statements. – Riccardo Murri Dec 02 '20 at 10:18
  • 1
    @MikeRapadas you were missing the `switch` reflection operation (e.g. `v.(type)`). I modified your benchmarks to use that in addition, and it turns out that using `switch` is far faster. Albeit that method comes with caveats - the types one is interested in must be explicitly defined to be useful. [benchmark results](https://gist.github.com/rrrix/8939a049a069615b83c9bf0fac5ca402). – Rick B Mar 03 '23 at 00:43
60

Use the reflect package:

Package reflect implements run-time reflection, allowing a program to manipulate objects with arbitrary types. The typical use is to take a value with static type interface{} and extract its dynamic type information by calling TypeOf, which returns a Type.

package main

import (
    "fmt"
    "reflect"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Println(reflect.TypeOf(b))
    fmt.Println(reflect.TypeOf(s))
    fmt.Println(reflect.TypeOf(n))
    fmt.Println(reflect.TypeOf(f))
    fmt.Println(reflect.TypeOf(a))
}

Produces:

bool
string
int
float64
[]string

Playground

Example using ValueOf(i interface{}).Kind():

package main

import (
    "fmt"
    "reflect"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Println(reflect.ValueOf(b).Kind())
    fmt.Println(reflect.ValueOf(s).Kind())
    fmt.Println(reflect.ValueOf(n).Kind())
    fmt.Println(reflect.ValueOf(f).Kind())
    fmt.Println(reflect.ValueOf(a).Index(0).Kind()) // For slices and strings
}

Produces:

bool
string
int
float64
string

Playground

Faheel
  • 2,435
  • 24
  • 33
Intermernet
  • 18,604
  • 4
  • 49
  • 61
  • reflect only displays the standard types. I am not able to get types of elements of a list container. – Rahul Nov 24 '13 at 04:09
  • I've updated my answer to include a slice of strings. Reflect works for any type. Please read the docs: http://golang.org/pkg/reflect/ & http://blog.golang.org/laws-of-reflection should be enough, although there are many SO questions related to reflection in Go that should help you out as well. – Intermernet Nov 24 '13 at 07:55
  • 5
    ughhh, how can I determine if the type is a string? `if reflect.TypeOf(err) == string`? – Alexander Mills Dec 20 '18 at 02:51
47

To get a string representation:

From http://golang.org/pkg/fmt/

%T a Go-syntax representation of the type of the value

package main
import "fmt"
func main(){
    types := []interface{} {"a",6,6.0,true}
    for _,v := range types{
        fmt.Printf("%T\n",v)
    }
}

Outputs:

string
int
float64
bool
globby
  • 609
  • 1
  • 7
  • 9
17

I would stay away from the reflect. package. Instead use %T

package main

import (
    "fmt"
)

func main() {
    b := true
    s := ""
    n := 1
    f := 1.0
    a := []string{"foo", "bar", "baz"}

    fmt.Printf("%T\n", b)
    fmt.Printf("%T\n", s)
    fmt.Printf("%T\n", n)
    fmt.Printf("%T\n", f)
    fmt.Printf("%T\n", a)
 }
harold ramos
  • 639
  • 7
  • 6
16

Best way is using reflection concept in Google.
reflect.TypeOf gives type along with the package name
reflect.TypeOf().Kind() gives underlining type

Jiten
  • 177
  • 1
  • 2
11

To be short, please use fmt.Printf("%T", var1) or its other variants in the fmt package.

pr-pal
  • 3,248
  • 26
  • 18
6

If we have this variables:

var counter int = 5
var message string  = "Hello"
var factor float32 = 4.2
var enabled bool = false

1: fmt.Printf %T format : to use this feature you should import "fmt"

fmt.Printf("%T \n",factor )   // factor type: float32

2: reflect.TypeOf function : to use this feature you should import "reflect"

fmt.Println(reflect.TypeOf(enabled)) // enabled type:  bool

3: reflect.ValueOf(X).Kind() : to use this feature you should import "reflect"

fmt.Println(reflect.ValueOf(counter).Kind()) // counter type:  int
Elie G.
  • 1,514
  • 1
  • 22
  • 38
Hamed Naeemaei
  • 8,052
  • 3
  • 37
  • 46
5

To get the type of fields in struct

package main

import (
  "fmt"
  "reflect"
)

type testObject struct {
  Name   string
  Age    int
  Height float64
}

func main() {
   tstObj := testObject{Name: "yog prakash", Age: 24, Height: 5.6}
   val := reflect.ValueOf(&tstObj).Elem()
   typeOfTstObj := val.Type()
   for i := 0; i < val.NumField(); i++ {
       fieldType := val.Field(i)
       fmt.Printf("object field %d key=%s value=%v type=%s \n",
          i, typeOfTstObj.Field(i).Name, fieldType.Interface(),
          fieldType.Type())
   }
}

Output

object field 0 key=Name value=yog prakash type=string 
object field 1 key=Age value=24 type=int 
object field 2 key=Height value=5.6 type=float64

See in IDE https://play.golang.org/p/bwIpYnBQiE

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
negi Yogi
  • 2,138
  • 2
  • 15
  • 20
5

You can check the type of any variable/instance at runtime either using the "reflect" packages TypeOf function or by using fmt.Printf():

package main

import (
   "fmt"
   "reflect"
)

func main() {
    value1 := "Have a Good Day"
    value2 := 50
    value3 := 50.78

    fmt.Println(reflect.TypeOf(value1 ))
    fmt.Println(reflect.TypeOf(value2))
    fmt.Println(reflect.TypeOf(value3))
    fmt.Printf("%T",value1)
    fmt.Printf("%T",value2)
    fmt.Printf("%T",value3)
}
t j
  • 7,026
  • 12
  • 46
  • 66
Kabeer Shaikh
  • 207
  • 3
  • 2
2

You can use: interface{}..(type) as in this playground

package main
import "fmt"
func main(){
    types := []interface{} {"a",6,6.0,true}
    for _,v := range types{
        fmt.Printf("%T\n",v)
        switch v.(type) {
        case int:
           fmt.Printf("Twice %v is %v\n", v, v.(int) * 2)
        case string:
           fmt.Printf("%q is %v bytes long\n", v, len(v.(string)))
       default:
          fmt.Printf("I don't know about type %T!\n", v)
      }
    }
}
Hasan A Yousef
  • 22,789
  • 24
  • 132
  • 203
  • 1
    You can also do this trick: `switch v := v.(type)` and then do this: `case int: fmt.Printf("Twice %v is %v\n", v, v * 2)` and `case string: fmt.Printf("%q is %v bytes long\n", v, len(v))`. The inner `v` variable in switch statement shadows original `v`, so inside case code block `v` assumend as variable of type that specified in case statement. – Arkemlar Apr 04 '21 at 22:30
2

For arrays and slices use Type.Elem():

a := []string{"foo", "bar", "baz"}
fmt.Println(reflect.TypeOf(a).Elem())
grossvater
  • 81
  • 5
2

I have organized the following.

  1. fmt %T : a Go-syntax representation of the type of the value
  2. reflect.TypeOf.String()
  3. reflect.TypeOf.Kind()
  4. type assertions

Example

package _test

import (
    "fmt"
    "reflect"
    "testing"
)

func TestType(t *testing.T) {
    type Person struct {
        name string
    }
    var i interface{}
    i = &Person{"Carson"}

    for idx, d := range []struct {
        actual   interface{}
        expected interface{}
    }{
        {fmt.Sprintf("%T", "Hello") == "string", true},
        {reflect.TypeOf("string").String() == "string", true},
        {reflect.TypeOf("string").Kind() == reflect.String, true},
        {reflect.TypeOf(10).String() == "int", true},
        {reflect.TypeOf(10).Kind() == reflect.Int, true},
        {fmt.Sprintf("%T", 1.2) == "float64", true},
        {reflect.TypeOf(1.2).String() == "float64", true},
        {reflect.TypeOf(1.2).Kind() == reflect.Float64, true},
        {reflect.TypeOf([]byte{3}).String() == "[]uint8", true},
        {reflect.TypeOf([]byte{3}).Kind() == reflect.Slice, true},
        {reflect.TypeOf([]int8{3}).String() == "[]int8", true},
        {reflect.TypeOf([]int8{3}).Kind() == reflect.Slice, true},
        {reflect.TypeOf(Person{"carson"}).Kind() == reflect.Struct, true},
        {reflect.TypeOf(&Person{"carson"}).Kind() == reflect.Ptr, true},
        {fmt.Sprintf("%v", i.(*Person)) == "&{Carson}", true},
        {fmt.Sprintf("%+v", i.(*Person)) == "&{name:Carson}", true},
    } {
        if d.actual != d.expected {
            t.Fatalf("%d | %s", idx, d.actual)
        }
    }
}

go playground

Carson
  • 6,105
  • 2
  • 37
  • 45
  • +1 Most of the time, the point of finding out if a variable is a string is because we'd want to do something conditionally based on that. If I only care about the string case then a switch statement is overkill. This is the only answer at the moment that shows multiple simple ways of performing the type check with a comparison operator instead of banally printing the type (for beginners, it's not obvious what you'd use as the comparator). – evantkchong Apr 29 '22 at 09:56
2

In case if you want to detect the type within if expression:

if str, ok := myvar.(string); ok {
    print("It's a string")
}

Or without type assertion (may produce errors):

if reflect.TypeOf(myvar).String() == "string" {
    print("It's a string")
}
artnikpro
  • 5,487
  • 4
  • 38
  • 40
0

you can use reflect.TypeOf.

  • basic type(e.g.: int, string): it will return its name (e.g.: int, string)
  • struct: it will return something in the format <package name>.<struct name> (e.g.: main.test)
littlepoint
  • 114
  • 6
-2

reflect package comes to rescue:

reflect.TypeOf(obj).String()

Check this demo