FROM @anachronistic:
BTW, in case it's not obvious (because after some talking with people it's definitely not obvious, and it wasn't obvious to me in the Go code I wrote months back), embedded types are more or less extend in Go (that is to say, they are the way to composition).
ex. I have a BlogPost struct that records the number of views a particular post has received. I realize that my RecordView method is not threadsafe, so I decide I want to lock a mutex, then update, then unlock (yes, atomic update is faster, but I'm really just proving a structural point here).
type BlogPost struct {
ID int
Views int
Visible bool
AllowComments bool
}
func (post *BlogPost) RecordView() {
post.Views++
}
I could add a field to my struct called _mutex (or whatever) and then call post._mutex.Lock() and post._mutex.Unlock() in my method.
type BlogPost struct {
ID int
Views int
Visible bool
AllowComments bool
_mutex sync.Mutex
}
func (post *BlogPost) RecordView() {
post._mutex.Lock()
post.Views++
post._mutex.Unlock()
}
That's for chumps. Embed dat shit homie, and extend BlogPost with the requisite methods.
type BlogPost struct {
ID int
Views int
Visible bool
AllowComments bool
sync.Mutex
}
func (post *BlogPost) RecordView() {
post.Lock()
post.Views++
post.Unlock()
}
I'll leave the "What happens if you embed multiple types that all implement the same interface?" question as an exercise for the reader.