The Go language has no classes, so there is no inheritance, so you can only combine various functions by embedding features (for convenience, we will call them embedding).
The simplest is the interface embedding interface, for example, we have defined Reader and Writer interfaces.
We can then combine them to define a new ReadWriter interface
This is equivalent to the following, but it avoids repeating the definition (Don’t repeat yourself).
The Go language also supports embedding interfaces in structs, but this requires a bit of understanding.
If we define a struct called ReadWriter, we want it to implement the Reader and Writer interfaces, and we already have instances of the corresponding reader and writer. Without the embedding feature, we might have to look like this.
We define Read and Write methods for ReadWriter, but then we don’t do anything specific, we just delegate the functionality to reader and writer objects. Obviously, there is no point in writing this code over and over again. We can use the embedding of the go language to eliminate this repetition, so we have this code
Do you see the difference? Yes, the field names reader and writer are removed from the front. At this point the compiler knows that you want to embed the Reader and Writer pointer into the ReadWriter structure. If you now have a
rw *ReaderWriter pointer, you can call the
rw.Write() methods directly, as if ReadWriter had defined them itself.
But how do you initialize a ReadWriter structure without a field name? This is where it’s easy for beginners to get confused. For embedding, the go language convention is that the field name is equivalent to the type name (minus the package name) and does not need to be specified on display.
That is, ReadWrite will have a property called Reader and a property called Writer, by which we can initialize ReadeWriter, for example
We have two ways to call the embed method
The first can be called directly via rw, and the second can be called via the agreed-upon rw.Reader. Generally speaking, the first call is the one you want to use for embedding.
However, what if the Reader interface has a method that is also a Reader? Then a naming conflict arises
To eliminate this conflict, the go language specifies that the fields and methods of the outer struct take precedence, as it is written
First, a field or method
Xhides any other item
Xin a more deeply nested part of the type.
That is, if the Reader interface has a method that is also Reader, then
rw.Reader refers to the Reader instance, and you cannot call the corresponding Reader method with `rw.
In fact, there is another conflict: ReadWriter embeds Reader and then owns a Reader field. But what is the problem if ReadWriter also defines a field named Reader?
Second, if the same name appears at the same nesting level, it is usually an error; However, if the duplicate name is never mentioned in the program outside the type definition, it is OK.
As long as you don’t reference them, you won’t report an error. Still, I would advise against showing off your skills and writing such incomprehensible code.