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

566

如何在Go中查找对象类型? 在Python中,我只需使用typeof获取对象的类型。同样,在Go中,是否有一种实现方式可以实现相同的功能?

这是我正在遍历的容器:

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

在这种情况下,我无法获得对象“lines”的类型,该对象是一个字符串数组。


标准参考在我的程序中不起作用。我应该包含源代码,我的错。 - Rahul
39
fmt.Printf("%T\n", var) - meh
16个回答

2
对于数组和切片,请使用 Type.Elem()
a := []string{"foo", "bar", "baz"}
fmt.Println(reflect.TypeOf(a).Elem())

2

如果你想在if表达式中检测类型:

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

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

if reflect.TypeOf(myvar).String() == "string" {
    print("It's a string")
}

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

go playground


大多数情况下,查找变量是否为字符串的目的是因为我们想基于此有条件地执行某些操作。如果我只关心字符串情况,那么使用 switch 语句就过于复杂了。目前,这是唯一一个展示了多种简单方法来使用比较运算符执行类型检查而不是单调地打印类型的答案(对于初学者来说,不清楚应该使用什么作为比较器)。 - evantkchong

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

1
你也可以使用这个技巧: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 语句中的变量类型。 - Arkemlar

0

你可以使用reflect.TypeOf

  • 基本类型(例如:intstring):它将返回其名称(例如:intstring
  • 结构体:它将返回格式为<包名>.<结构体名>的内容(例如:main.test

-3

reflect 包来拯救:

reflect.TypeOf(obj).String()

请查看此演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接