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/uaNi4mHDmVNow, 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.