This is a creation in Article, where the information may have evolved or changed.
"Go language Combat" reading notes, not to be continued, welcome to sweep code attention flysnow_org to the public, the first time to see follow-up notes.
An embedded type, or nested type, is a way to declare an existing type in a new type, which is important for code reuse.
In other languages, inheritance can do the same thing, but in the go language, there is no concept of inheritance, the way Go advocates code reuse is a combination, so this is the meaning of the embedded type, combination rather than inheritance, so go will be more flexible.
1234567891011121314151617181920212223 24252627 |
type Reader Interface {Read (p []byte ) (n int , err Error)}type Writer interface {Write (p []byte ) (n int , err Error)}type Closer interface {Close () error} type Readwriter interface {readerwriter}type readcloser interface {readercloser}type writecloser interface
{Writercloser} |
The above is the standard library io package, we commonly used interfaces, you can see the ReadWriter interface is embedded Reader and Reader interface and combined into a new interface, so we do not have to repeat the definition is embedded in the interface of the method, directly through the embedding can be. Embedding types also apply to struct types, let's look at an example:
12345678910 |
type struct string string} type struct string} |
After embedding, the embedded type is called the inner type, the newly defined type is called the external type, and this is the user inner type, and the admin external type.
With an embedded type, all fields, methods, markers, and so on that are associated with the internal type, are owned by the outsourced type, just like the external type itself, which achieves the purpose of the code shortcut multiplexing combination, and the definition is very simple, just declare the name of the type.
At the same time, external types can also add their own methods, field properties, etc., can easily extend the functionality of external types.
123456 |
func Main () {ad:=admin{user{"Zhang San","zhangsan@flysnow.org"},"Administrator"}fmt. Println ("can be called directly, named:", Ad.name) fmt. Println ("can also be called by an internal type, named:", Ad.user.name) fmt. Println ("but the newly added attribute can only be called directly, the level is:", Ad.level)} |
The above is the use of embedded type, you can see that we are in the initialization, the use of the literal value of the way, so to be initialized by the structure of its definition, first initialize the user internal type, and then initialize the new level properties.
For internal types of properties and method access, we can access it either directly from an external type or through an internal type, but we have new method attribute fields for external types that can only be accessed using external types because the internal types do not have these.
Of course, an external type can also declare a field or method with the same name to cover the internal type, which is more than the case method.
123456789101112131415161718192021222324 |
func main() {ad:=admin{user{"Zhang San","zhangsan@flysnow.org"},"Administrator"}ad.user.sayhello () Ad.sayhello ()}typeUserstruct{NamestringEmailstring}typeAdminstruct{Userlevelstring} func (u user) sayHello() {FMT. Println ("Hello,i am a user")} func (a admin) sayHello() {FMT. Println ("Hello,i am a Admin")} |
The inner type user has a sayHello method, the external type overrides it, the same name is overridden sayHello , and then we access the two types of methods in the Main method, the printout:
12 |
Hello,i am a userhello,i am a admin |
From the output, the method sayHello is successfully overwritten.
The power of the
Embedding type is also reflected in the following: If an internal type implements an interface, the external type is also considered to implement the interface. Let's look at a little bit of the example.
123456789101112131415161718 |
func main () {ad:=admin{user{, },< Span class= "string" > "Administrator" }sayhello (ad.user) //use user as parameter SayHello (AD) //use admin as parameter }type Hello interface {hello ()}func (u user) Span class= "title" >hello () FMT. Println ( "hello,i am a User" )}func sayhello (h Hello)
{H.hello ()} |
This example of the original structure type user and admin the definition of the same, a new interface Hello , and then let user the type implementation of the interface, finally we define a sayHello method, it accepts an Hello interface type parameters, and finally we in the main function to demonstrate the time , it can be called normally, whether it is a user type or if the admin type is passed as a parameter to sayHello the method.
Here we can explain the implementation of the admin interface Hello , but we do not show the declaration type admin implementation, so this implementation is implemented through the internal type user , because it admin contains user all the method functions, so also implemented the interface Hello .
Of course the external type can be re-implemented, just like the example above to overwrite the same name method. The point here is that no matter how we overwrite the same name, it doesn't affect the internal type, we can also access its methods, property fields, etc. by accessing the internal type.
The definition of embedded type is go to facilitate us to expand or modify the existing type of behavior, is designed to promote the concept of composition, so we often use the combination, flexible use of the combination, expand more of the type structure we need.
"Go language Combat" reading notes, not to be continued, welcome to sweep code attention flysnow_org to the public, the first time to see follow-up notes.