Skip to content

reflect: add TypeAssert #62121

Open
@dsnet

Description

Consider the following benchmark:

func Benchmark(b *testing.B) {
	v := reflect.ValueOf(new(time.Time)).Elem()
	b.ReportAllocs()
	for i := 0; i < b.N; i++ {
		_ = v.Interface().(time.Time)
	}
}

This currently prints:

Benchmark-24    	37673833	        29.74 ns/op	      24 B/op	       1 allocs/op

Since the underlying time.Time is addressable, the Interface method must make a copy of it.

However, one primary reason to use the Interface method is to then assert it to a particular concrete type.

I propose the addition of:

// AssertTo is semantically equivalent to:
//    v2, ok := v.Interface().(T)
func AssertTo[T any](v reflect.Value) (T, bool)

which avoids the allocation since the value is never boxed in an interface.

Usage would then look like:

t, ok := reflect.AssertTo[time.Time](v)

and naturally matches type-assertion construct in the Go language itself.


Ideally, this would be a method on Value, but we don't have #49085.
If we did, the signature would be:

func (Value) AssertTo[T any]() (T, bool)

and usage would be more natural as:

t, ok := v.AssertTo[time.Time]()

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Type

No type

Projects

  • Status

    Accepted

Relationships

None yet

Development

No branches or pull requests

Issue actions