* Chris Hopkins <cbehopk...@gmail.com> [181010 12:04]:
> Hi,
> I appreciate this is not possible, but realised I never understood why (so 
> have just been working around it).
> Example code at:
> https://play.golang.org/p/BgFL9T0KiC7
> 
> I can create a struct with other structs as a member. I then get all the 
> fields and methods associated with that member.
> But you can't cast from that master struct back to the member struct. 
> i.e. I can create a type T with subtype S and operate on the members and 
> data within S, but can't cast T to S.
> I guessed that when you define type S, it exists as effectively a pointer 
> to a struct, and then members within that struct are an indexed offset from 
> that pointer. The act of creating S within T is simply extending that 
> definition so that T's new fields start where S's finished. Casting back 
> from T should therefore be trivial, but clearly it isn't :-)
> 
> I'm sure there's a good reason, but it escapes me at the moment. Any ideas?

While my answer below is correct and more technical, I think the answer
Burak Serdar gave, that embedding is composition not inheritance, may be
more helpful in understanding why you might have believed that it should
work when it doesn't.

However, in the interest of clearer communication between gophers, I am
going to wax pedantic.  Go does not have any syntactic construct called
a cast.  It has conversions and type assertions.

Type assertions are used to change a value from a concrete type to an
interface type which it implements, an interface type to the concrete
type currently held by that value, or an interface type to another
interface type which the concrete type also implements.

Some type assertions can be determined to be illegal at compile time,
others can produce a runtime panic (if the v, ok = x.(T) assignment form
is not used).

Conversions come in two flavors:  those that change the underlying
representation of the value and those that don't.  The ones that do
either convert from one numeric type to another (e.g. uint to float64),
or convert to or from a string type (e.g. []byte to string).

For all other conversions, the underlying types of the value being
converted and the type to which it is being converted must be identical
(a little extra verbiage is necessary for pointers, but the idea is the
same).

Conversions can always be type-checked at compile time and never produce
a runtime panic (out-of-memory notwithstanding).

In your example, c = Bob(f), you are attempting a conversion of f (type
Fred) to type Bob.  But Bob and Fred do not have identical underlying
types so you cannot convert f to type Bob.

You can, however, say c = f.Bob, since embedding Bob (the type) creates
a field named Bob.

...Marvin

-- 
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