Skip to content

Conversation

cuiweixie
Copy link

@cuiweixie cuiweixie commented Aug 27, 2025

Fixes #

Target Release

1.14.x

Rollback Plan

  • If a change needs to be reverted, we will roll out an update to the code within 7 days.

Changes to Security Controls

Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.

CHANGELOG entry

  • This change is user-facing and I added a changelog entry.
  • This change is not user-facing.

@cuiweixie cuiweixie requested a review from a team as a code owner August 27, 2025 08:43
Copy link
Contributor

Changelog Warning

Currently this PR would target a v1.14 release. Please add a changelog entry for in the .changes/v1.14 folder, or discuss which release you'd like to target with your reviewer. If you believe this change does not need a changelog entry, please add the 'no-changelog-needed' label.

@radeksimko
Copy link
Member

Hi @cuiweixie
Can you explain the motivation behind the change?

@radeksimko radeksimko added the waiting-response An issue/pull request is waiting for a response from the community label Aug 27, 2025
@cuiweixie
Copy link
Author

Hi @cuiweixie Can you explain the motivation behind the change?

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.

@radeksimko
Copy link
Member

What was posted above seems to be just an AI summary of the technical differences between the two approaches. My question was more what problem does the change solve in the context of this codebase and why should we change it.

While I acknowledge the minor technical differences summarised, there is no specific bug, risk or problem being solved here (from what I can tell) and the current implementation works just fine.

Thanks.

@radeksimko radeksimko closed this Aug 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting-response An issue/pull request is waiting for a response from the community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants