简体   繁体   English

相反的reflect.TypeOf

[英]Reverse of reflect.TypeOf

I want to retrieve back the type of value I saved once. 我想找回我保存一次的值的类型。 I used reflect.Typeof() and saved the type. 我使用了reflect.Typeof()并保存了类型。 then try to use switch type. 然后尝试使用开关类型。 the type will always be "*reflect.rtype ". 该类型将始终为“ * reflect.rtype”。 I couldn't retrieve either by type assertion. 我无法通过类型断言来检索。

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 游乐场: https : //play.golang.org/p/kqDo4DPYjra

A reflect.Type holds no value you could type assert (actually you could, but that could only be reflect.Type , not what you want). 一个reflect.Type包含您可以键入assert的值(实际上可以,但是只能是reflect.Type ,而不是您想要的值)。 A reflect.Type is just a type descriptor (which you obtained from a value). 一个reflect.Type只是一个类型描述符(从值中获得)。

However, you could create a value of the type represented by reflect.Type , and you can type-assert the values from that you originally wanted. 但是,您可以创建一个由reflect.Type表示的类型的值,并且可以从您最初想要的值中键入值。

To create a new pointer value, use reflect.New() . 要创建一个新的指针值,请使用reflect.New() To obtain the pointed value, use Value.Elem() . 要获取目标值,请使用Value.Elem() These are all wrapped in a reflect.Value . 这些都包装在一个reflect.Value To unwrap it, use Value.Interface() . 要解开它,请使用Value.Interface()

For example: 例如:

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

This will output (try it on the Go Playground ): 这将输出(在Go Playground上尝试):

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

Also if you don't want to create new values just test the type, "save" the reflect.Type descriptors of the types you're interested in, and use a normal switch on the type: 另外,如果您不想创建新值,只需测试类型,“保存”您感兴趣的类型的reflect.Type描述符,并在类型上使用常规switch

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

This will output (try it on the Go Playground ): 这将输出(在Go Playground上尝试):

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

Recommended reading: The Go Blog: The Laws of Reflection 推荐读物: 围棋博客:反思法则

Depending on what you want to do, you don't necessarily need to do that with a type assertion. 根据您要执行的操作,您不一定需要使用类型断言来执行此操作。 v.(reflect.Type).Kind() will tell you what kind of type it is (eg, reflect.Bool , reflect.Float64 , reflect.Int , etc.). v.(reflect.Type).Kind()将告诉您它是哪种类型(例如, reflect.Boolreflect.Float64reflect.Int等)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM