go - reflect.TypeOf 的反转

标签 go reflection types type-assertion

我想取回我曾经保存过的值的类型。我使用了 reflect.Typeof() 并保存了类型。然后尝试使用开关类型。类型将始终为“*reflect.rtype”。我无法通过类型断言检索任何一个。

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var alltypes []interface{}

    alltypes = append(alltypes, reflect.TypeOf(true))
    alltypes = append(alltypes, reflect.TypeOf(0.0))
    alltypes = append(alltypes, reflect.TypeOf(0))
    fmt.Printf("%T\t%q\n", alltypes, alltypes)

    for _, v := range alltypes {
        fmt.Printf("%T\t%q\n", v, v)
        res, ok := v.(bool)
        fmt.Println("res: ", res, " ok: ", ok)
        switch v.(type) {
        default:
            fmt.Printf("unexpected type %T\n", v)
        case bool:
            fmt.Println("bool type!")
        case int:
            fmt.Println("int type!")
        case float64:
            fmt.Println("float64 type!")
        }
    }

}

Playground :https://play.golang.org/p/kqDo4DPYjra

最佳答案

A reflect.Type没有任何值(value)你可以type assert (实际上你可以,但那只能是 reflect.Type,而不是你想要的)。 reflect.Type 只是一个类型描述符(您从值中获得)。

但是,您可以创建一个由 reflect.Type 表示的类型的值,并且您可以对您最初想要的值进行类型断言。

要创建一个新的指针值,请使用 reflect.New() .要获得指向值,请使用 Value.Elem() .这些都包裹在 reflect.Value 中.要打开它,请使用 Value.Interface() .

例如:

for _, v := range alltypes {
    fmt.Printf("%T\t%q\n", v, v)
    value := reflect.New(v.(reflect.Type)).Elem().Interface()
    switch value.(type) {
    default:
        fmt.Printf("unexpected type %T\n", v)
    case bool:
        fmt.Println("bool type!")
    case int:
        fmt.Println("int type!")
    case float64:
        fmt.Println("float64 type!")
    }
}

这将输出(在 Go Playground 上尝试):

[]interface {}  ["bool" "float64" "int"]
*reflect.rtype  "bool"
bool type!
*reflect.rtype  "float64"
float64 type!
*reflect.rtype  "int"
int type!

此外,如果您不想创建新值,只需测试类型,“保存”您感兴趣的类型的 reflect.Type 描述符,并使用普通的 切换类型:

var (
    TypeBool    = reflect.TypeOf(true)
    TypeFloat64 = reflect.TypeOf(0.0)
    TypeInt     = reflect.TypeOf(0)
)

func main() {
    var alltypes []interface{}

    alltypes = append(alltypes, reflect.TypeOf(true))
    alltypes = append(alltypes, reflect.TypeOf(0.0))
    alltypes = append(alltypes, reflect.TypeOf(0))
    fmt.Printf("%T\t%q\n", alltypes, alltypes)

    for _, v := range alltypes {
        fmt.Printf("%T\t%q\n", v, v)
        switch v {
        default:
            fmt.Printf("unexpected type %T\n", v)
        case TypeBool:
            fmt.Println("bool type!")
        case TypeInt:
            fmt.Println("int type!")
        case TypeFloat64:
            fmt.Println("float64 type!")
        }
    }
}

这将输出(在 Go Playground 上尝试):

[]interface {}  ["bool" "float64" "int"]
*reflect.rtype  "bool"
bool type!
*reflect.rtype  "float64"
float64 type!
*reflect.rtype  "int"
int type!

推荐阅读:The Go Blog: The Laws of Reflection

关于go - reflect.TypeOf 的反转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55995917/

相关文章:

types - 在内部使用列表时未定义相互递归类型

swift - 字节字符串作为 Swift 4 中的数据

c# - 结构 - 现实生活中的例子?

sockets - 在断开连接的情况下不使用 goto 语句改进网络代码

json - 使用查询在 Golang 中处理 API?

vb.net - 如何使用属性本身获取属性的名称

c# - 使用类型泛型时如何正确地将类转换为抽象类?

go - 不改变接收器的接口(interface)

string - 查找字符串中子字符串的索引,指定起始索引

java - 将 Protocol Buffer 序列化为 XML?