How to find the type of an object in Go?

huangapple go评论86阅读模式
英文:

How to find the type of an object in Go?

问题

在Go语言中,你可以使用reflect.TypeOf函数来获取对象的类型。在你的代码中,你可以这样使用它来获取lines对象的类型:

fmt.Printf("%T", lines)

这将打印出lines对象的类型。在你的代码中,你可以将fmt.Printf语句修改为上述代码来获取lines对象的类型。

英文:

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.

答案1

得分: 667

Go的反射包提供了用于检查变量类型的方法。

以下代码片段将打印出字符串、整数和浮点数的反射类型。

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

}

输出结果:

string
int
float64

可以在此链接中查看代码的运行示例:http://play.golang.org/p/XQMcUVsOja

更多文档请参考:http://golang.org/pkg/reflect/#Type

英文:

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

答案2

得分: 578

我找到了3种在运行时返回变量类型的方法:

使用字符串格式化

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

使用反射包

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

使用类型切换

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

每种方法都有不同的最佳用例:

  • 字符串格式化 - 简短且占用内存较少(不需要导入反射包)

  • 反射包 - 当需要更多关于类型的详细信息时,可以使用完整的反射功能

  • 类型切换 - 允许对类型进行分组,例如将所有int32、int64、uint32、uint64类型识别为"int"类型。

英文:

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"

答案3

得分: 60

使用reflect包:

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

输出结果:

bool
string
int
float64
[]string

Playground

使用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()) // 对于切片和字符串
}

输出结果:

bool
string
int
float64
string

Playground

英文:

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:

<!-- language: lang-none -->

bool
string
int
float64
[]string

Playground

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

package main

import (
	&quot;fmt&quot;
	&quot;reflect&quot;
)

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

	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:

<!-- language: lang-none -->

bool
string
int
float64
string

Playground

答案4

得分: 47

获取字符串表示:

从http://golang.org/pkg/fmt/中:

> %T 值的Go语法表示的类型

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

输出:

string
int
float64
bool
英文:

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 &quot;fmt&quot;
func main(){
	types := []interface{} {&quot;a&quot;,6,6.0,true}
	for _,v := range types{
		fmt.Printf(&quot;%T\n&quot;,v)
	}
}

Outputs:

string
int
float64
bool

答案5

得分: 17

我会避免使用reflect包,而是使用%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)
}
英文:

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

package main

import (
   	&quot;fmt&quot;
)

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

    fmt.Printf(&quot;%T\n&quot;, b)
 	fmt.Printf(&quot;%T\n&quot;, s)
 	fmt.Printf(&quot;%T\n&quot;, n)
    fmt.Printf(&quot;%T\n&quot;, f)
  	fmt.Printf(&quot;%T\n&quot;, a)
 }

答案6

得分: 16

最好的方法是在Google中使用反射概念。
reflect.TypeOf 返回类型和包名。
reflect.TypeOf().Kind() 返回底层类型。

英文:

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

答案7

得分: 11

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

英文:

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

答案8

得分: 6

如果我们有以下变量:

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

1: 使用 fmt.Printf %T 格式:要使用此功能,您应该 import "fmt"

fmt.Printf("%T \n", factor)   // factor 的类型为 float32

2: 使用 reflect.TypeOf 函数:要使用此功能,您应该 import "reflect"

fmt.Println(reflect.TypeOf(enabled)) // enabled 的类型为 bool

3: 使用 reflect.ValueOf(X).Kind():要使用此功能,您应该 import "reflect"

fmt.Println(reflect.ValueOf(counter).Kind()) // counter 的类型为 int
英文:

If we have this variables:

var counter int = 5
var message string  = &quot;Hello&quot;
var factor float32 = 4.2
var enabled bool = false

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

fmt.Printf(&quot;%T \n&quot;,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

答案9

得分: 5

获取结构体字段的类型

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("对象字段 %d 键=%s 值=%v 类型=%s \n",
			i, typeOfTstObj.Field(i).Name, fieldType.Interface(),
			fieldType.Type())
	}
}

输出结果

对象字段 0 键=Name 值=yog prakash 类型=string 
对象字段 1 键=Age 值=24 类型=int 
对象字段 2 键=Height 值=5.6 类型=float64

在IDE中查看:https://play.golang.org/p/bwIpYnBQiE

英文:

To get the type of fields in struct

package main

import (
  &quot;fmt&quot;
  &quot;reflect&quot;
)

type testObject struct {
  Name   string
  Age    int
  Height float64
}

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

答案10

得分: 5

你可以在运行时使用 "reflect" 包的 TypeOf 函数或使用 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)
}

请注意,以上代码是用于演示目的的,用于展示如何检查变量/实例的类型。

英文:

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 (
   &quot;fmt&quot;
   &quot;reflect&quot;
)

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

    fmt.Println(reflect.TypeOf(value1 ))
    fmt.Println(reflect.TypeOf(value2))
    fmt.Println(reflect.TypeOf(value3))
    fmt.Printf(&quot;%T&quot;,value1)
    fmt.Printf(&quot;%T&quot;,value2)
    fmt.Printf(&quot;%T&quot;,value3)
}

答案11

得分: 2

你可以使用interface{}..(type),就像这个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: interface{}..(type) as in this playground

package main
import &quot;fmt&quot;
func main(){
    types := []interface{} {&quot;a&quot;,6,6.0,true}
    for _,v := range types{
        fmt.Printf(&quot;%T\n&quot;,v)
        switch v.(type) {
	    case int:
		   fmt.Printf(&quot;Twice %v is %v\n&quot;, v, v.(int) * 2)
	    case string:
		   fmt.Printf(&quot;%q is %v bytes long\n&quot;, v, len(v.(string)))
	   default:
		  fmt.Printf(&quot;I don&#39;t know about type %T!\n&quot;, v)
	  }
    }
}

答案12

得分: 2

对于数组和切片,请使用Type.Elem()

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

对于数组和切片,请使用Type.Elem()

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

For arrays and slices use Type.Elem():

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

答案13

得分: 2

我已经整理好了以下内容。

  1. fmt %T:值的Go语法表示的类型
  2. reflect.TypeOf.String()
  3. reflect.TypeOf.Kind()
  4. 类型断言

示例

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

<kbd>go playground</kbd>

英文:

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 (
	&quot;fmt&quot;
	&quot;reflect&quot;
	&quot;testing&quot;
)

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

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

<kbd>go playground</kbd>

答案14

得分: 2

如果你想在if表达式中检测类型,可以使用以下代码:

if str, ok := myvar.(string); ok {
    print("这是一个字符串")
}

或者不使用类型断言(可能会产生错误):

if reflect.TypeOf(myvar).String() == "string" {
    print("这是一个字符串")
}
英文:

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

if str, ok := myvar.(string); ok {
print(&quot;It&#39;s a string&quot;)
}

Or without type assertion (may produce errors):

if reflect.TypeOf(myvar).String() == &quot;string&quot; {
print(&quot;It&#39;s a string&quot;)
}

答案15

得分: 0

你可以使用reflect.TypeOf

  • 基本类型(例如:intstring):它将返回类型的名称(例如:intstring
  • 结构体:它将以<包名>.<结构体名>的格式返回结果(例如:main.test
英文:

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 &lt;package name&gt;.&lt;struct name&gt; (e.g.: main.test)

答案16

得分: -2

reflect 包来拯救:

reflect.TypeOf(obj).String()

查看这个 演示

英文:

reflect package comes to rescue:

reflect.TypeOf(obj).String()

Check this demo

huangapple
  • 本文由 发表于 2013年11月24日 10:08:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/20170275.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定