最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

go - How to use switch type on value of reflect.TypeOf(value) - Stack Overflow

programmeradmin1浏览0评论

How is it possible to use a switch type on the value of reflect.TypeOf(value)

import (
    "fmt"
    "reflect"
)

func main() {
    var value int = 123
    t := reflect.TypeOf(value)
    switch tv := t.(type) {
    case int:
        fmt.Println("type: INT")
    }
    fmt.Println(t)
}

How is it possible to use a switch type on the value of reflect.TypeOf(value)

import (
    "fmt"
    "reflect"
)

func main() {
    var value int = 123
    t := reflect.TypeOf(value)
    switch tv := t.(type) {
    case int:
        fmt.Println("type: INT")
    }
    fmt.Println(t)
}
Share Improve this question asked Jan 29 at 9:22 clarkkclarkk 1 4
  • 1 You can’t use a type switch, because the type of t is always reflect.Type – Mr_Pink Commented Jan 29 at 9:26
  • 1 This example is a bit silly, because you already know the concrete type. What's the actual use case? Is reflection really needed? – jub0bs Commented Jan 29 at 11:11
  • Yes, normally you would just use a type switch with the original value, rather than using reflect to create an obfuscated version of the same type switch. It’s only really useful if all you have is a reflect.Type, but that almost always comes from a reflect.Value, in which case you would still use a regular type switch. – Mr_Pink Commented Jan 29 at 14:19
  • This question is similar to: How to find the type of an object in Go?. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – M_x Commented Feb 3 at 4:19
Add a comment  | 

3 Answers 3

Reset to default 0

t's type is the reflect.Type interface type, and the concrete type stored in it is always the unexported *reflect.rtype pointer type descriptor, so there's no sense type-switching on that.

Use a switch statement and compare to other reflect.Type values like this:

for _, v := range []any{
    int(123), "foo", float64(1.0),
} {
    t := reflect.TypeOf(v)

    switch t {
    case reflect.TypeOf(int(0)):
        fmt.Println("type: INT")
    case reflect.TypeOf(""):
        fmt.Println("type: STRING")
    default:
        fmt.Println("type: other:", t)
    }
}

This will output (try it on the Go Playground):

type: INT
type: STRING
type: other: float64

If you have to run this many times, you can cache the type descriptors you're interested in:

var (
    typeInt    = reflect.TypeOf(int(0))
    typeString = reflect.TypeOf("")
)

Then the switch:

switch t {
case typeInt:
    fmt.Println("type: INT")
case typeString:
    fmt.Println("type: STRING")
default:
    fmt.Println("type: other:", t)
}

This outputs the same. Try this one on the Go Playground.

You might consider switching on the reflect.Kind instead of reflect.Type, to me this code is more readable and easier to maintain as well defined constants can be used instead of creating extra vars in memory.
Go Playground example

package main

import (
    "fmt"
    "reflect"
)

type namedStruct struct{}

func main() {
    for _, v := range []any{
        123, "foo", 1.0, struct{}{}, namedStruct{}, &namedStruct{},
    } {
        t := reflect.TypeOf(v)
        switch k := t.Kind(); k {
        case reflect.Int:
            fmt.Println(k.String())
        case reflect.String:
            fmt.Println(k.String())
        case reflect.Float64, reflect.Float32:
            fmt.Println(k.String())
        default:
            fmt.Println("other:", k.String())
        }
    }
}

This prints:

int
string
float64
other: struct
other: struct
other: ptr

Instead of a type switch, use t.Kind() to determine the type.

package main

import (
    "fmt"
    "reflect"
)

func main() {
    var value int = 123
    t := reflect.TypeOf(value)

    switch t.Kind() {
    case reflect.Int:
        fmt.Println("type: INT")
    case reflect.String:
        fmt.Println("type: STRING")
    default:
        fmt.Println("type: UNKNOWN")
    }

    fmt.Println("Reflect Type:", t)
}
  • reflect.Type.Kind() returns a reflect.Kind value that represents the underlying type (e.g., reflect.Int, reflect.String).
  • switch can be used on t.Kind() to determine the type.
发布评论

评论列表(0)

  1. 暂无评论