TypeOf without an instance and passing result to a func

Yes, it’s possible. The trick is to start from a pointer to the type (whose value can be a typed nil, that’s perfectly OK), and then use Type.Elem() to get the reflect.Type descriptor of the pointed type (the base type).

See some examples:

t := reflect.TypeOf((*int)(nil)).Elem()
fmt.Println(t)

t = reflect.TypeOf((*http.Request)(nil)).Elem()
fmt.Println(t)

t = reflect.TypeOf((*os.File)(nil)).Elem()
fmt.Println(t)

Output (try it on the Go Playground):

int
http.Request
os.File

See related questions:

Golang reflect: Get Type representation from name?

How to get the string representation of a type?

If you want to pass around the types and use them in switches, you can create and store them in global variables once like this, and refer to the global vars:

var (
    intType         = reflect.TypeOf((*int)(nil))
    httpRequestType = reflect.TypeOf((*http.Request)(nil))
    osFileType      = reflect.TypeOf((*os.File)(nil))
    int64Type       = reflect.TypeOf((*uint64)(nil))
)

func printType(t reflect.Type) {
    switch t {
    case intType:
        fmt.Println("Type: int")
    case httpRequestType:
        fmt.Println("Type: http.request")
    case osFileType:
        fmt.Println("Type: os.file")
    case int64Type:
        fmt.Println("Type: uint64")
    default:
        fmt.Println("Type: Other")
    }
}

func main() {
    printType(intType)
    printType(httpRequestType)
    printType(osFileType)
    printType(int64Type)
}

Output of the above (try it on the Go Playground):

Type: int
Type: http.request
Type: os.file
Type: uint64

But honestly, if you’re using it like this way and you’re not using reflect.Type‘s methods, then creating constants is much easier and more efficient. It could look like this:

type TypeDesc int

const (
    typeInt TypeDesc = iota
    typeHttpRequest
    typeOsFile
    typeInt64
)

func printType(t TypeDesc) {
    switch t {
    case typeInt:
        fmt.Println("Type: int")
    case typeHttpRequest:
        fmt.Println("Type: http.request")
    case typeOsFile:
        fmt.Println("Type: os.file")
    case typeInt64:
        fmt.Println("Type: uint64")
    default:
        fmt.Println("Type: Other")
    }
}

func main() {
    printType(typeInt)
    printType(typeHttpRequest)
    printType(typeOsFile)
    printType(typeInt64)
}

Output is the same. Try it on the Go Playground.

Leave a Comment