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.

func main() {    var b bytes.Buffer    fmt.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.

func Fprint(w io.Writer, a ...interface{}) (n 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 fmt.Fprint the Function.

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.

func main() {    var b bytes.Buffer    fmt.Fprint(&b, "Hello World")    var w io.Writer    w = &b    fmt.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.

func main() {    var a animal    var c cat    a=c    a.printInfo()    //使用另外一个类型赋值    var d dog    a=d    a.printInfo()}type animal interface {    printInfo()}type cat inttype dog intfunc (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.

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.

func main() {    var c cat    //值作为参数传递    invoke(c)}//需要一个animal接口作为参数func invoke(a animal){    a.printInfo()}type animal interface {    printInfo()}type cat int//值接收者实现animal接口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.

func main() {    var c cat    //指针作为参数传递    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.

func main() {    var c cat    //值作为参数传递    invoke(c)}//需要一个animal接口作为参数func invoke(a animal){    a.printInfo()}type animal interface {    printInfo()}type cat int//指针接收者实现animal接口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:

./main.go:10: cannot use c (type cat) as type animal in argument to invoke:    cat does not implement animal (printInfo 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.

func main() {    var c cat    //指针作为参数传递    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.