douti9286 2019-05-05 20:02
浏览 83
已采纳

相反的reflect.TypeOf

I want to retrieve back the type of value I saved once. I used reflect.Typeof() and saved the type. then try to use switch type. the type will always be "*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
", alltypes, alltypes)

    for _, v := range alltypes {
        fmt.Printf("%T\t%q
", v, v)
        res, ok := v.(bool)
        fmt.Println("res: ", res, " ok: ", ok)
        switch v.(type) {
        default:
            fmt.Printf("unexpected type %T
", 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

  • 写回答

2条回答 默认 最新

  • douhan5547 2019-05-05 20:12
    关注

    A reflect.Type holds no value you could type assert (actually you could, but that could only be reflect.Type, not what you want). A reflect.Type is just a type descriptor (which you obtained from a value).

    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.

    To create a new pointer value, use reflect.New(). To obtain the pointed value, use Value.Elem(). These are all wrapped in a reflect.Value. To unwrap it, use Value.Interface().

    For example:

    for _, v := range alltypes {
        fmt.Printf("%T\t%q
    ", v, v)
        value := reflect.New(v.(reflect.Type)).Elem().Interface()
        switch value.(type) {
        default:
            fmt.Printf("unexpected type %T
    ", 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):

    []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:

    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
    ", alltypes, alltypes)
    
        for _, v := range alltypes {
            fmt.Printf("%T\t%q
    ", v, v)
            switch v {
            default:
                fmt.Printf("unexpected type %T
    ", 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):

    []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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 目详情-五一模拟赛详情页
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line