Documenting reflect.TypeOf((*Foo)(nil)).Elem()?

261 views
Skip to first unread message

Matthew Dempsky

unread,
Mar 23, 2015, 2:28:08 PM3/23/15
to golang-dev
TL;DR: Is it worth documenting the "reflect.TypeOf((*Foo)(nil)).Elem()" idiom somewhere?  E.g., in reflect.TypeOf's documentation or as an example?


I wrote some code using package reflect over the weekend.  One of the problems I needed to solve was determining whether a type implemented a particular interface, which in turn required finding the reflect.Type value for that interface.

I distinctly remembered that Go had typed nil pointers (but forgot that didn't extend to nil interfaces), so my first instinct was to write "reflect.TypeOf(MyInterface(nil))".  However, that just returns nil, not the reflect.Type for MyInterface.

When that didn't work, I looked again through the package reflect godocs and the linked "The Laws of Reflection" blog post, but didn't see anything explaining how to get a reflect.Type for an interface type.  I mostly searched for mentions of "interface", so perhaps I overlooked something.

Those options exhausted, I resorted to Googling and eventually found a stackoverflow entry (http://stackoverflow.com/questions/7132848/how-to-get-the-reflect-type-of-an-interface) that suggested this:

    reflect.TypeOf((*MyInterface)(nil)).Elem()

In retrospect, that makes sense and seems reasonable, but it wasn't among my immediate ideas.  It seems like something clever enough to warrant a mention in the reflection documentation.

Searching around, I see this isn't the first time this question has come up:

Craig

unread,
Mar 23, 2015, 2:52:38 PM3/23/15
to Matthew Dempsky, golang-dev

+1. I don't find much about reflection intuitive (maybe that says more about my intuition than this package), so documentation is probably the next best thing.

--
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matthew Dempsky

unread,
Mar 23, 2015, 4:30:29 PM3/23/15
to golang-dev
So my first stab at documenting this would be something like:

-// TypeOf returns the reflection Type of the value in the interface{}.
-// TypeOf(nil) returns nil.
+// TypeOf returns the reflection Type that represents the dynamic type of i.
+// If i is a nil interface value, TypeOf returns nil.
+//
+// As interface types are only used for static typing, a common idiom to find
+// the reflection Type for an interface type Foo is to use a pointer value:
+//     fooType := reflect.TypeOf((*Foo)(nil)).Elem()

It's a bit wordy, but some rationale:

Values only have concrete (i.e., non-interface) types, so technically "reflection Type of the value" is unambiguously the dynamic type, but that seems needlessly subtle.  Also, most function documentation refer to values by the parameter variable name.  So "reflection Type of the value in i" seems less helpful than "reflection Type of the dynamic type of i".

"reflection Type of the dynamic type of i" felt clunky, so I used "reflection Type that represents the dynamic type of i" to mimic other documentation.

Explicitly mentioning "dynamic type" also helps contrast with why interface types need to be special cased.

Finally, TypeOf(nil) is unambiguously using a nil interface value, but it seems maybe worthwhile to clarify that it's specifically the nil *interface* value that causes TypeOf to return nil, to help contrast against the nil *pointer* value used in the example.

Jan Mercl

unread,
Mar 23, 2015, 4:56:09 PM3/23/15
to golang-dev
On Mon, Mar 23, 2015 at 7:28 PM 'Matthew Dempsky' via golang-dev <golan...@googlegroups.com> wrote:

> TL;DR: Is it worth documenting the "reflect.TypeOf((*Foo)(nil)).Elem()" idiom somewhere?

Considering source code a documentation sometimes superior to documentation...: https://github.com/golang/go/blob/master/src/reflect/set_test.go#L166

-j



minux

unread,
Mar 23, 2015, 5:00:35 PM3/23/15
to Matthew Dempsky, golang-dev
On Mon, Mar 23, 2015 at 2:27 PM, 'Matthew Dempsky' via golang-dev <golan...@googlegroups.com> wrote:
TL;DR: Is it worth documenting the "reflect.TypeOf((*Foo)(nil)).Elem()" idiom somewhere?  E.g., in reflect.TypeOf's documentation or as an example?

I think it should document in the laws of reflection blog post. Or as an example in the reflect package.

If you think about it, TypeOf take an interface{}, and interface{} can only store actual types, not another
interface, so the idiom makes sense.
Reply all
Reply to author
Forward
0 new messages