Skip to content

Conversation

@cuiweixie
Copy link
Contributor

why you might use reflect.TypeFor instead of reflect.TypeOf in Go.


Background

In Go, the reflect package provides two similar-looking functions:

  • reflect.TypeOf(x)
    Takes a value x and returns its reflect.Type.
    Example:

    t := reflect.TypeOf(123) // type: int
  • reflect.TypeFor[T]() (introduced in Go 1.22)
    A generic function that returns the reflect.Type for a type parameter T without needing a value.
    Example:

    t := reflect.TypeFor[int]() // type: int

Why use reflect.TypeFor instead of reflect.TypeOf?

  1. No value needed

    • reflect.TypeOf requires an actual value at runtime.
      If you only know the type (not a value), you have to create a dummy value:
      t := reflect.TypeOf((*MyStruct)(nil)).Elem()
    • reflect.TypeFor works directly with the type parameter:
      t := reflect.TypeFor[MyStruct]()
      This is cleaner and avoids allocating or creating dummy values.
  2. Compile-time type safety

    • With reflect.TypeOf, the type is determined from a runtime value, so mistakes may only show up at runtime.
    • With reflect.TypeFor, the type is determined at compile time from the generic type parameter, so it’s safer and clearer.
  3. Better for generic code

    • In generic functions, you often have a type parameter T but no value of type T.
      reflect.TypeOf can’t be used without creating a zero value:
      func PrintType[T any]() {
          var zero T
          fmt.Println(reflect.TypeOf(zero))
      }
      With reflect.TypeFor, you can simply do:
      func PrintType[T any]() {
          fmt.Println(reflect.TypeFor[T]())
      }
  4. Avoids unnecessary allocations

    • Creating a dummy value for reflect.TypeOf may allocate memory (especially for composite types).
    • reflect.TypeFor avoids this overhead entirely.

Summary Table

Feature reflect.TypeOf reflect.TypeFor (Go 1.22+)
Requires a value ✅ Yes ❌ No
Works without allocation ❌ Sometimes allocates ✅ Yes
Compile-time type safety ❌ Runtime only ✅ Compile-time
Good for generics ❌ Needs zero value ✅ Directly works

Recommendation:
Use reflect.TypeFor when:

  • You know the type at compile time (especially in generic code).
  • You don’t have or don’t want to create a value.
  • You want cleaner, safer, and allocation-free code.

Use reflect.TypeOf when:

  • You already have a value and want its type at runtime.

@CLAassistant
Copy link

CLAassistant commented Aug 17, 2025

CLA assistant check
All committers have signed the CLA.

Copy link
Member

@mholt mholt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, why not. Thank you!

@mholt mholt merged commit b15ed9b into caddyserver:master Aug 18, 2025
23 checks passed
@francislavoie francislavoie added this to the v2.10.1 milestone Aug 22, 2025
mohammed90 pushed a commit to cedricziel/caddy that referenced this pull request Aug 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants