如何在Go中找到对象的类型?


387

如何在Go中找到对象的类型?在Python中,我只是typeof用来获取对象的类型。类似地,在Go中,是否可以实现相同的方法?

这是我要迭代的容器:

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

在这种情况下,我无法获取对象线的类型,即字符串数组。


在我的程序中工作的标准参考文献。我本该把源代码包括在内。
拉胡尔

5
fmt.Printf("%T\n", var)
meh 18/09/09

Answers:


470

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

}

输出:

Hello, playground
string
int
float64

请参阅:http : //play.golang.org/p/XQMcUVsOja以查看实际效果。

此处提供更多文档:http : //golang.org/pkg/reflect/#Type


反映不是为我工作。我已经更新了问题。在这种情况下,我包括了代码段。
拉胡尔

462

我发现了三种在运行时返回变量类型的方法:

使用字符串格式

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"
    //... etc
    default:
        return "unknown"
    }
}

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

  • 字符串格式-占用空间少,占用空间小(无需导入反射包)

  • 反射包-当需要有关类型的更多详细信息时,我们可以使用全反射功能

  • 类型断言-允许对类型进行分组,例如将所有int32,int64,uint32,uint64类型识别为“ int”


3
看来您可以摆脱variable t,所以t := v.(type)变为v.(type),并且_ = t不再需要。
Akavall '17

3
基于准系统基准,反射方法出奇地更有效gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
Mike Rapadas

case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String())。使用反射打印类型的fmt软件包
Fantasy_RQG

50

使用反射包:

包反射实现了运行时反射,从而允许程序处理任意类型的对象。典型的用法是使用静态类型interface {}获取值,并通过调用TypeOf来提取其动态类型信息,该类型返回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))
}

产生:

bool
string
int
float64
[]string

操场

使用示例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
}

产生:

bool
string
int
float64
string

操场


反映只显示标准类型。我无法获取列表容器的元素类型。
拉胡尔

我更新了我的答案,以包含一小部分字符串。Reflect适用于任何类型。请阅读文档:golang.org/pkg/reflectblog.golang.org/laws-of-reflection应该够了,虽然有相关的围棋反射许多做题应该帮助你为好。
Intermernet

2
ughhh,如何确定类型是否为字符串?if reflect.TypeOf(err) == string
亚历山大·米尔斯

43

要获取字符串表示形式:

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

非常务实的方法+1
Bijan 2014年

16

我会远离反思。包。而是使用%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)
 }

13

最好的方法是在Google中使用反射概念。
reflect.TypeOf提供类型以及包名称
reflect.TypeOf().Kind()提供下划线类型


1
我认为这是一个更好的答案
Ezio

9

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


4

您可以使用“ 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)
}

4

获取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())
   }
}

输出量

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

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


0

您可以使用reflect.TypeOf

  • 基本类型(例如:intstring):它会返回它的名称(例如:intstring
  • 结构:它会在格式返回的东西<package name>.<struct name>(如:main.test

0

如果我们有以下变量:

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

1:fmt.Printf%T格式:要使用此功能,您应该导入“ fmt”

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

2:reflect.TypeOf函数:要使用此功能,您应该导入“ reflect”

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

3:reflect.ValueOf(X).Kind():要使用此功能,您应该导入“ reflect”

fmt.Println(reflect.ValueOf(counter).Kind()) // counter type:  int

0

您可以使用:interface{}..(type)在这个游乐场

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.