Thanks Axel for the detail explanation. Make sense now. :) On Monday, December 5, 2016 at 12:51:41 PM UTC+5:30, Axel Wagner wrote: > > 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 <kavirajk...@gmail.com > <javascript:>> 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...@googlegroups.com <javascript:>. >> 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.