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.

Reply via email to