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