添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Currently, to get a reflect.Type value for a type T , one has to use the following expression

t := reflect.TypeOf((*T)(nil)).Elem()

It would be nice if we could have a lighter and more readable expression to get the reflect.Type value of a type. Maybe generics can help, if they are added to Go v2.

Obviously, we can do that. But the goal is to get a reflect.Type value without having to declare a useless value.

We need to be able to write something like t := reflect.Type(int) or t := reflect.Type(anyType).

We need this when we want to pass the type value as argument to a function for instance. It is dumb to declare a variable we won't use just to get the type value. The expression I gave returns the type value without needing to declare a variable. It's just cumbersome to use and read.

Obviously, we can do that. But the goal is to get a reflect.Type value without having to declare a useless value.

The "useless" variable is used to achive your goal ;-)

We need to be able to write something like t := reflect.Type(int) or t := reflect.Type(anyType).

So far only some builtin functions can take a type as their first argument. Allowing that for user code in a package is a big language change. You'd need to make this proposal much more complete for such change to be even considered.

We need this when we want to pass the type value as argument to a function for instance. It is dumb to declare a variable we won't use just to get the type value.

If you pass - as you call it - a 'type value' to a function, the variable that you can directly pass to reflect.TypeOf is already declared - it's the parameter variable:

func f(x interface{}) reflect.Type { return reflect.TypeOf(x) }

edit: grammar

What I mean by "type value" is a value of type reflect.Type.

Currently I defined my function as func g(t reflect.Type). I currently expected that the user would have to write g(reflect.TypeOf((*T)(nil)).Elem()) which as you understand is pretty unreadable.

Your last suggestion is much more elegant. Here is an example: https://play.golang.org/p/jrqOUu5bZD4
It's not perfect, but it simplify the task for the user. If you allow me, I'll adopt it until it is fixed in Go2.

My goal was simply to report an issue to eventually clean up in Go2. I don't have a solution to suggest. As I said, I suspect the solution might be linked to the generic system where a function may be parameterized by a type.

changed the title Cleanup proposal for Go v2: simplify the reflect.TypeOf((*T)(nil)).Elem() expression reflect: Go 2: simplify the reflect.TypeOf((*T)(nil)).Elem() expression Aug 26, 2018

My point would probably be more clear if the title was : 

reflect: Go 2: reflect.Type literals 

I can't say how often the reflect.TypeOf((*T)(nil)).Elem() pattern is used. I saw it documented as an idiomatic way to get a reflect.Type literal. It's been discussed here https://grokbase.com/t/gg/golang-nuts/153sxr7gqp/go-nuts-reflect-typeof-without-allocating-an-instance for instance. It comes up from time to time which implies that people do need such reflect.Type literals.

My goal was only to add a radar blip on this issue for the Go 2 developer team so they can fix it if it's easy. It might come for free with generics. Who can say now ?

A typical use case is when we need to build a map with Go types as keys and various kind of values, like an encoding function or specific actions for instance.

The actual different expressions to get the equivalent of a type literal are not simple and readable.

reflect: Go 2: simplify the reflect.TypeOf((*T)(nil)).Elem() expression reflect: Go 2: reflect.Type literals Aug 27, 2018

The contracts proposal would provide a way to express this using type parameters (as @chmike hinted at above):

func TypeOf2(type T)() reflect.Type {
    return reflect.TypeOf((*T)(nil)).Elem()

With usage as:

t := reflect.TypeOf2(io.Reader)()

(Of course TypeOf2 is a terrible name)