What is an interface

The Go interface is a data type that defines all common methods together, and any other type that implements those methods implements the interface.

In go, interfaces have the following features:

  • It can contain signatures for zero or more methods
  • Only the signature of the method is defined, not the implementation
  • You don’t need to explicitly declare an interface; you just need to implement the corresponding methods

Interface Definition

Use the keyword interface to define an interface, which is a collection of methods. Interface definition format:

typeInterface name interface{Method name 1(possible parameters, do not pass) Return type Method name 2(possible parameters, do not pass) Return type... }Copy the code

Such as:

type People interface {
    Show(name string, age int) (id int, err error)  
    Set(name string, age int)
}
Copy the code

Interface implementation

In the GO language, the implementation of an interface is implicit and does not require a display declaration to implement the interface. When a type provides definitions for all methods in the interface, it is said to implement the interface. The following is an example of an interface:

package main

import (
    "fmt"
)

type USB interface {
    Name() string
    Connect()
}

typePhoncConnecter struct {name string} PhoncConnecter struct {name string} Func (PC PhoncConnecter) Name() string {return pc.name
}

func (pc PhoncConnecter) Connect() {
    fmt.Println(pc.name)
}

func mainVar a USB // declare a variable of interface type a = PhoncConnecter{"PhoneC"} // Since PhoncConnecter implements the interface USB, we can assign instances of this type to the interface variable a.connect () // The second, Call var b = PhoncConnecter{} b.name = after assigning a value to the structure"b"Var c USB // declare a variable of interface type c = b. c onnect()}Copy the code

The output is:

PhoneC
b
Copy the code

The above example defines the USB interface and declares two methods Name() and Connect(). It then defines the PhoncConnecter structure and declares a variable Name. It also declares two methods Name() and Connect() on the structure through the method properties. In GO, as long as you implement a method defined in an interface, the default represents inheritance similar to that in other languages, inheriting that interface, so in the main function, you can achieve code reuse by declaring the interface and structure to do the corresponding operations.

The value type of the interface

1. Internal performance of the interface

An interface can be thought of as internally represented by a tuple (type, value). Type is the basic concrete type of the interface, and value is the value of the concrete type.

An interface is a collection of interfaces. It is an abstract data type. An interface variable can refer to the value of any concrete data type that implements all the methods of the interface.

The interface variable stores two parts of information, one is the concrete value assigned to the interface variable (the value of the interface implementer), and the other is the descriptor of the type of the value (the type of the interface implementer), in the form of (value, concrete type) instead of (value, interface type).

package main

import (
	"fmt"
)

type Test interface {
	Tester()
}

type MyFloat float64

func (m MyFloat) Tester() {
	fmt.Println(m)
}

func describe(t Test) {
	fmt.Printf("Interface type: %T, value: %v\n", t, t)
}

func main() {var t Test f := MyFloat(89.7) t = f describe(t) t.tester ()}Copy the code

Running results:

Interface type: main.MyFloat, value: 89.7 89.7Copy the code

2. Empty interface

An empty interface is an interface that contains no methods and is represented as interface {}. Because of this, all types implement empty interfaces.

Although empty interfaces are useless, they are useful when you need to store any type of value, because empty interfaces can store any type of data.

package main

import (
	"fmt"
)

func describe(i interface{}) {
	fmt.Printf("Type = %T, value = %v\n", i, i)
}

func main() {// Any type of variable passed in can be s :="Hello World"
    i := 55
    strt := struct {
        name string
    }{
        name: "Naveen R",
    }
    describe(s)
    describe(i)
    describe(strt)
}
Copy the code

Running results:

Type = string, value = Hello World
Type = int, value = 55
Type = struct { name string }, value = {Naveen R}
Copy the code

Type assertion

Interface {} can be used to pass any type of variable to a function, but for the inside of the function, the variable is still of type interface{} (empty interface type), not the type of the argument passed in.

Conversion of interface types to common types is called type assertion (runtime determination), and type assertion is used to extract the underlying value of the interface, syntax: I.(T)

func printArray(arR interface{}){// ArR is an empty interface, not an Array typefor _, v: = range arr{
        fmt.Print(v,"") }     fmt.Println() }Copy the code

Interface types can be converted to slice types through type assertions

func printArray(arr interface{}){// Implement type conversion with assertion A,_ := arr.([]int)for _,v:=range a{
        fmt.Println(v, "")
    }
    fmt.Println()
}
Copy the code

When using type assertions, it is best to determine whether the assertion is successful

b,ok := a.(T)
if ok {
    ...
}
Copy the code

4. Type judgment

The syntax for type determination is similar to that for type assertion, in the syntax i.(type) for type assertion, type type should be replaced by the type conversion keyword type. Type assertions can be used with switch statements to determine:

package main

import (  
    "fmt"
)

func findType(i interface{}) {  
    switch i.(type) {
    case string:
        fmt.Printf("String: %s\n", i.(string))
    case int:
        fmt.Printf("Int: %d\n", i.(int))
    default:
        fmt.Printf("Unknown type\n")
    }
}
func main() {  
    findType("Naveen"FindType) findType (77) (89.98)}Copy the code

Running results:

String: Naveen
Int: 77
Unknown type
Copy the code

Use of interfaces

1. Embedded interfaces

An interface can contain one or more other interfaces, which is equivalent to listing the methods of these embedded interfaces directly in the outer interface. For example, the interface File contains all the methods for ReadWrite and Lock, plus a Close() method.

type ReadWrite interface {
    Read(b Buffer) bool
    Write(b Buffer) bool
}

type Lock interface {
    Lock()
    Unlock()
}

type File interface {
    ReadWrite
    Lock
    Close()
}
Copy the code

2. Assign interface variables

An instance of an object implementing an interface can be assigned to the interface, or another interface can be assigned to the interface.

  • If a type implements an interface, you can assign an instance of the type to the interface variable

  • Assign interfaces A and B through interfaces. If interface A is A subset of interface B, variables of type B are assigned to variables of type A

package main

import (
	"bytes"
	"io"
	"os"
	// "time"
)

func mainWriter var w IO.Writer // A w = os.stdout w = new (bytes.buffer) // w = time.second // error, ReadWriteCloser // B ReadWriteCloser = OS.Stdout // File ReadWriteCloser interface w = RWC}Copy the code

3. Use interfaces to achieve polymorphism

Go language polymorphism is to assign different types of instances of implementing interfaces to interface variables so that interface methods have different behaviors.

package main

import "fmt"

type MyGreeting interface {
	Greet(name string) string
}

type EnglishGreeting struct {

}

type ChinesGreeting struct {

}

func (this *EnglishGreeting) Greet(name string) string {
	return "Hello " + name
}

func (this *ChinesGreeting) Greet(name string) string {
	return "Hello" + name
}

func main() {
	var greet MyGreeting = new(EnglishGreeting)
	fmt.Println(greet.Greet("Bill"))

	greet = new(ChinesGreeting)
	fmt.Println(greet.Greet("Bill"))}Copy the code

Running results:

Hello Bill. Hello BillCopy the code