You need to distinguish between "the zero value of it's type" and "the zero (reflect.)Value". The docs here mean the latter, not the former. What is happening is, that in case of a nil-interface (w and in), the interface gets passed "as is" into reflect.ValueOf, which takes an interface{}. That is, as those are already interfaces, they don't get wrapped, but you just pass the interface header as is. And as they are nil, the interface header has two zero fields, there is no type or dynamic value that reflect could give you a handler for, so reflect.ValueOf gives you an invalid reflect.Value. For the other values, though, there *is* a dynamic value to be packed into the interface{}. Even though they might have the zero value of their type, they do come with a type. So when you pass it to reflect.ValueOf, an interface-header is constructed with a type-field pointing to the respective generated type-info and the value field pointing to a zero value of that type (or, in the case of *int, just set to that pointer, namely nil).
You can remove the distinction between passing interfaces and passing concrete types, by passing a *pointer* to reflect.ValueOf and using Value.Elem() to get to the value: https://play.golang.org/p/uaNi4mHDmV Now, you always pass a concrete type (in the case of w, for example, it's *io.Writer) which gets packed into the interface{} and passed to reflect.ValueOf. Elem() then unpacks that interface{} and follows the pointer. In the case of w, unwrapping will give you a pointer to that io.Writer interface value (not the non-existent thing packed in it) and following will give you a nil io.Writer. A nil io.Writer is still a valid reflect.Value, with the type io.Writer. So, there are three take-aways: * Kind() is invalid only on the zero-value of a reflect.Value, not on the reflect.Value representing the zero Value of any type. I.e. it's invalid only if you give reflect something without a dynamic type (such as a nil interface) * Interfaces are purely static types, so if you pass an interface as a different interface, the static information of what methods are on that interface gets erased. If you want to preserve this type information, you need to pass a non-interface type (such as a pointer to an interface). * Usage of reflect is subtle and difficult. Most gophers shouldn't use it for that reason alone. On Mon, Dec 5, 2016 at 6:55 AM, Kaviraj Kanagaraj < kavirajkanaga...@gmail.com> wrote: > Sry for the typo. Its true that Kind() returns "Invalid" if IsValid > returns False. But still docs seems to be misleading. It says "If v is > the zero Value (IsValid returns false), Kind returns Invalid." > > according to doc, all the variables in the code supposed to have a kind of > "Invalid" (since all the variables have zero value) in here > https://play.golang.org/p/RoIAXsxhIF > > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.