简体   繁体   中英

How to find the type of an object in Go?

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.

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:

Hello, playground
string
int
float64

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

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

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 assertions

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 assertions - allows grouping types, for example recognize all int32, int64, uint32, uint64 types as "int"

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

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

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)
 }

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

简而言之,请在 fmt 包中使用fmt.Printf("%T", var1)或其其他变体。

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

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)
}

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

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

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)
      }
    }
}

you can use reflect.TypeOf .

  • basic type(eg: int , string ): it will return its name (eg: int , string )
  • struct: it will return something in the format <package name>.<struct name> (eg: main.test )

For arrays and slices use Type.Elem() :

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

You can see this demo. It demonstrate how to show a const variable's type. https://go.dev/play/p/o89rrRj9mPM

reflect package comes to rescue:

reflect.TypeOf(obj).String()

Check this demo

You can just use the fmt package fmt.Printf() method, more information: https://golang.org/pkg/fmt/

example: https://play.golang.org/p/aJG5MOxjBJD

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM