Struct composition with Go(dave.cheney.net) |
Struct composition with Go(dave.cheney.net) |
client, server := net.Pipe()
var buf bytes.Buffer
client = &recordingConn {
Conn: client,
Writer: io.MultiWriter(client, &buf),
}
While it seemingly works, it seems confusing to assign client to an internal field of a new struct, and then overwriting that same client variable with the newly created struct...not to mention passing it into MultiWriter.Anyway, I like those short posts like this. I've done similar things with embedding and struct "reconstruction" in order to elicit more testable code. It's powerful and useful, indeed.
Compare:
client, server := net.Pipe()
var buf bytes.Buffer
client = &recordingConn {
Conn: client,
Writer: io.MultiWriter(client, &buf),
}
vs tempClient, server := net.Pipe()
var buf bytes.Buffer
client = &recordingConn {
Conn: tempClient,
Writer: io.MultiWriter(tempClient, &buf),
}
The latter is less confusing to me.(context: i am no gopher)
(edit/tangent: i wonder how method calls from inside method calls are resolved when the names are ambiguous?)
I tried to write an example that demonstrates why I don't think the ambiguity you're referring to is possible.
Edit: On further thought, this looks to me like composition with automatic delegation (a huge productivity benefit of inheritance). It is unusual because the combined class also implements the interfaces because of Go's interface rules, but I think that the late-binding to implementations is more similar to composition.
Inheritance implies is-a, and implies that you can modify some of the internal workings of the class you're inheriting from.
Embedding is strictly has-a. It's really no different than having a member variable in any other language... there's just some syntactic sugar to make it a little nicer to access the member's methods and fields (and the methods "count" for fulfilling interfaces).
The accessibility of inner struct methods from the outer struct is a syntactic convenience.
Java: https://gist.github.com/jaekwon/8025b9f3a482b3219a21 Go: https://gist.github.com/jaekwon/0f6e5555ab6a592aa4c8
Once you Go, you never go back. ;)
ex
type A struct{}
func (a *A)GetSelf()*A{return a}
type B struct{ A }
b:=&B{A{}}
b.GetSelf() returns type A , not type BIt gets even more confusing when you start embedding interfaces in structs.