Go Language Practical Notes (ix) | Go interface

Source: Internet
Author: User
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 interface is a convention, which is an abstract type, unlike the specific types we see, such as int, map, slice, and so on. The specific type, we can know what it is, and can know what to do with it, but the interface is not the same, the interface is abstract, it has only a set of interface methods, we do not know its internal implementation, so we do not know what the interface is, but we know what it can do with the method provided.

Abstraction is the advantage of the interface, it does not have to be tied to specific implementation details, we just need to define the interface, tell the coder what it can do, so that we can separate the specific implementation, so that the coding will be more flexible, the ability to adapt is very strong.

12345
func Main ()  {var b bytes. Bufferfmt.fprint (&b,"Hello World") fmt. Println (B.string ())}

The above is an example of using an interface, we first look at the fmt.Fprint implementation of the function.

1234567
func Fprint (w io.) Writer, a ... Interface {})int, err error)  {p: = Newprinter () p.doprint (a) n, err = W.write (p.buf) p.free ()  Return}

From the source code above, we can see that the fmt.Fprint first parameter of the function is io.Writer this interface, so as long as the implementation of the specific type of the interface can be passed as a parameter to the fmt.Fprint function, but bytes.Buffer the implementation of the io.Writer interface, it can be passed as a parameter to the fmt.Fprintfunction.

Internal implementation

We mentioned earlier that an interface is a type that defines the behavior, which is abstract, and the behavior of these definitions is not implemented directly by the interface, but by the user-defined type implemented by the method. If a user-defined type implements all the methods of an interface type declaration, the user-defined type implements the interface, so that the value of the user-defined type can be assigned to the value of the interface type.

1234567
func Main ()  {var"Hello World")var w io. Writerw = &bfmt. Println (W)}

In this example, because the bytes.Buffer interface is implemented, we can assign a value that assigns the value io.Writer of the w = &b defined type to the value of the interface type.

After the assignment operation, if we call the interface method, we call the corresponding method of the Stored user-defined type, here we can call the user-defined type 实体类型 .

We can define many types, let them implement an interface, then these types can be assigned to this interface, when the interface method calls, in fact, is the corresponding 实体类型 method of the call, which is polymorphic.

 1234567891011121314151617181920212223242526 
 func  main   ()   {var  a animalvar  c Cata=ca.printinfo () //use another type assignment  var  d doga=da.printinfo ()}type  animal interface  {printinfo ()} type  cat int  type  dog int  func   (c cat)  printinfo   ()   {fmt. Println ( "a cat" )}func   (d dog)  printinfo   ()   {fmt. Println ( "a Dog" )} 

The above example shows a polymorphic. We define an interface animal , then define two types cat and dog implement the interface animal . When used, the value of the type, the value of the cat c type dog is d assigned to the value of the interface animal a , and then a the method executed separately printInfo , you can see the different output.

12
A cata dog

We look at the layout of the interface values after the value of the interface is assigned. The value of the interface is a two-word-length data structure, the first word contains a pointer to the internal table structure, the information stored in this inner list, 实体类型 and the associated method set, and the second word contains a pointer to the stored 实体类型 value. So the value structure of the interface is actually two pointers, which can also indicate that the interface is actually a reference type.

Method set

We all know that if you want to implement an interface, you must implement all the methods provided by this interface, but when implementing the method, we can use the pointer receiver implementation, can also use the value of the receiver implementation, there is a difference between the two, we have a good analysis of the difference between the two.

 1234567891011121314151617181920 
 
      
       func  
       main  
        ()   {
       var  c cat
       //value passed as parameter  Invoke (c)}
       //requires a animal interface as a parameter  
       func  invoke   (a animal)   {A.printinfo ()} 
       type  animal 
       interface  {printinfo ()} 
       type  cat 
       int  
       //value receiver implements animal interface  
       func   (c cat)  printinfo   ()   {fmt. Println (
        "a Cat" )} 
      

Or the original example to change, add a invoke function, the function receives an animal interface type parameters, in the case of passing parameters, the value of the type is also cat c passed, the running program can execute normally. Now let's change it a little bit, using a type cat of pointer &c as a parameter pass.

12345
func Main ()  {var c cat//pointer passed as parameter Invoke (&C)}

Just modify this one place, the other remains the same, we run the program, the discovery can also be performed normally. By this example, we can conclude that the interface is implemented by the entity type when the interface is implemented by the value recipient, whether it is a value of the entity type or a pointer to the entity type value .

Let's try to change the receiver to a pointer.

 1234567891011121314151617181920 
 
      
       func  
       main  
        ()   {
       var  c cat
       //value passed as parameter  Invoke (c)}
       //requires a animal interface as a parameter  
       func  invoke   (a animal)   {A.printinfo ()} 
       type  animal 
       interface  {printinfo ()} 
       type  cat 
       int  
       //pointer receiver implements animal interface  
       func   (c *cat)  printinfo   ()   {fmt. Println (
        "a Cat" )} 
      

In this example, the receiver of the implementation interface is changed to a pointer, but when the parameter is passed, we still pass the value, click Run Program, the following exception prompt appears:

12
./main.go:10:cannot use C (typetype in argument to Invoke:cat does not implement animal (PR intInfo method has pointer receiver)

It has been clearly told in the hints that the cat interface is not implemented animal because printInfo the method has a pointer receiver, so cat the value of the type c cannot be used as an interface type animal parameter. Let's change it a little bit and pass the pointer as a parameter.

12345
func Main ()  {var c cat//pointer passed as parameter Invoke (&C)}

The other is unchanged, just to use the parameters of the previous values, instead of using pointers as parameters, we run the program, we can run normally. This shows that when an entity type implements an interface with a pointer receiver, only pointers to that type are considered to implement the interface

Now let's summarize both of these rules, first in terms of whether the method recipient is a value or a pointer.

Methods Receivers Values
(T T) T and *t
(t *t) *t

The table above can be interpreted as: if it is a value recipient, the value and pointer of the entity type can implement the corresponding interface, and if it is the pointer receiver, then only the type pointer can implement the corresponding interface.

Next we look at the angle of whether the entity type is a value or a pointer.

Values Methods Receivers
T (T T)
*t (T T) and (T *t)

The above table can be read as follows: The value of a type can only implement the interface of the receiver of the value, and a pointer to a type can implement either the interface of the value receiver or the interface of the pointer receiver.

Standard library

"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.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.