【问题标题】:How to find the type of an object in Go?如何在 Go 中查找对象的类型?
【发布时间】:2013-12-08 20:00:10
【问题描述】:

如何在 Go 中找到对象的类型?在 Python 中,我只是使用typeof 来获取对象的类型。同样在 Go 中,有没有办法实现相同的?

这是我从中迭代的容器:

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

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

【问题讨论】:

  • 标准参考在我的程序中不起作用。我应该把源代码包括在内。
  • fmt.Printf("%T\n", var)

标签: go go-reflect


【解决方案1】:
推荐的答案 Go Language

Go 反射包具有检查变量类型的方法。

下面的sn-p会打印出一个字符串、整数和浮点数的反射类型。

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

【讨论】:

  • 反映不是为我工作。我已经更新了这个问题。在这种情况下,我已经包含了代码 sn-p。
【解决方案2】:

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

使用string formatting

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

使用reflect package

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

使用type assertions

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”

【讨论】:

  • 看来t这个变量可以去掉了,所以t := v.(type)变成v.(type)_ = t就不需要了。
  • 基于准系统基准,反射方法的效率惊人地高gist.github.com/mrap/7f08c9549289b6aea2923c27888e7e3e
  • case 'T': p.fmt.fmtS(reflect.TypeOf(arg).String())。 fmt 包使用反射打印类型
  • 请注意,v.(type) 仅适用于 switch 语句。
【解决方案3】:

使用reflect 包:

反射包实现运行时反射,允许程序 操作任意类型的对象。典型的用途是采取 具有静态类型 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

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()) // For slices and strings
}

生产:

bool
string
int
float64
string

Playground

【讨论】:

  • reflect 只显示标准类型。我无法获取列表容器的元素类型。
  • 我已更新我的答案以包含一段字符串。 Reflect 适用于任何类型。请阅读文档:golang.org/pkg/reflectblog.golang.org/laws-of-reflection 应该足够了,尽管有许多与 Go 中的反射相关的 SO 问题也应该对您有所帮助。
  • ughhh,如何确定类型是否为字符串? if reflect.TypeOf(err) == string?
【解决方案4】:

获取字符串表示:

来自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

【讨论】:

    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          您可以在运行时使用“反射”包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)
          }
          

          【讨论】:

            【解决方案9】:

            获取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

            【讨论】:

              【解决方案10】:

              如果我们有这个变量:

              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 type: float32
              

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

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

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

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

              【讨论】:

                【解决方案11】:

                你可以使用: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)
                      }
                    }
                }
                

                【讨论】:

                • 你也可以这样做:switch v := v.(type),然后这样做:case int: fmt.Printf("Twice %v is %v\n", v, v * 2)case string: fmt.Printf("%q is %v bytes long\n", v, len(v))。 switch 语句中的内部v 变量隐藏了原始v,因此在case 代码块v 中假定为case 语句中指定类型的变量。
                【解决方案12】:

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

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

                【讨论】:

                  【解决方案13】:

                  你可以使用reflect.TypeOf

                  • 基本类型(例如:intstring):它将返回其名称(例如:intstring
                  • struct:它将返回格式为&lt;package name&gt;.&lt;struct name&gt;的内容(例如:main.test

                  【讨论】:

                    【解决方案14】:

                    你可以看到这个演示。它演示了如何显示 const 变量的类型。 https://go.dev/play/p/o89rrRj9mPM

                    【讨论】:

                    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                    【解决方案15】:

                    reflect 包来救援:

                    reflect.TypeOf(obj).String()
                    

                    检查这个demo

                    【讨论】:

                      【解决方案16】:

                      您可以只使用 fmt 包中的 fmt.Printf() 方法,更多信息:https://golang.org/pkg/fmt/

                      示例: https://play.golang.org/p/aJG5MOxjBJD

                      【讨论】:

                        猜你喜欢
                        • 2010-09-25
                        • 2016-02-19
                        • 2011-10-16
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-10-23
                        • 2016-04-14
                        相关资源
                        最近更新 更多