Go does not provide the typical, type-driven notion of subclassing,
but it does have the ability to “borrow” pieces of an implementation by embedding types within a struct or interface
interface embedding
Embed two interfaces to form a new one. It is a union of the embedded interfaces.
Only interfaces can be embedded within interfaces.
// io packagetype Reader interface {Read(p []byte) (n int, err error)}type Writer interface {Write(p []byte) (n int, err error)}// ReadWriter is the interface that combines the Reader and Writer interfaces.type ReadWriter interface {ReaderWriter}
struct embedding**bufio package
list the types within the struct but does not give them field names
// ReadWriter stores pointers to a Reader and a Writer.// It implements io.ReadWriter.type ReadWriter struct {*Reader // *bufio.Reader*Writer // *bufio.Writer}
bufio.ReadWriter not only has the methods of bufio.Reader and bufio.Writer, but also satisfies all three interfaces: io.Reader, io.Writer, and io.ReadWriter.
an embedded field alongside a regular, name field
type Job struct {Command string*log.Logger}// initializingfunc NewJob(command string, logger *log.Logger) *Job {return &Job{command, logger}}job := &Job{command, log.New(os.Stderr, "Job: ", log.Ldate)}// The Job type has the methods of *log.Loggerjob.Println("starting now...")//refer to an embedded field directly, using type namejob.Logger.Println("refer directly")
the rules to resolve name conflicts**
- A field or method
Xhides any other itemXin a more deeply nested part of the type. - If the same name appears at the same nesting level, it is usually an error;
However, if the duplicate name is never mentioned outside the type definition, it is OK. (NOT in the same struct)
it is OK, inner field is never mentioned outside the type definition
type inner1 struct {field string}type inner2 struct {field string}type outer struct {inner1inner2}func main() {out := outer{inner1{"inner1"},inner2{"inner2"},}fmt.Println(out)}
Ambiguous reference
Duplicate field
