A preliminary interpretation of the interface related authoring method in Golang

  • 2020-05-30 20:20:18
  • OfStack

An overview of the
If goroutine and channel are the two cornerstones of Go concurrency, then interfaces are the key to data types in Go programming. In the actual programming of Go, almost all data structures revolve around interfaces, which are the core of all data structures in Go.
The interface in the Go language is a collection of methods (method set) that specify the behavior of an object: if it (any data type) can do these things, it can be used here.

Definition and use of interfaces

Such as


type I interface{
    Get() int
    Put(int)
 
}

This defines an interface that contains two functions, Get and Put

Ok, one of my interfaces implements this interface:


type S struct {val int}
func (this *S) Get int {
    return this.val
}
func (this *S)Put(v int) {
    this.val = v
 
}

This structure, S, implements the interface I

interface in Go

Here are some examples of interface:


func SomeFunction(w interface{Write(string)}){
    w.Write("pizza")
 
}

In this case, interface is directly defined in the parameter, which is special...


func weirdFunc( i int ) interface{} {
  if i ==  0 {
    return "zero"
  }
  return i;
}

Connection KouFu values
We can assign one object instance that implements the interface to the interface, or we can assign another interface to the interface.

(1) assignment by object instance

Before assigning an object instance to an interface, make sure that the object implements all the methods of the interface. Consider the following example:


type Integer int
func (a Integer) Less(b Integer) bool {
 return a < b
}
func (a *Integer) Add(b Integer) {
 *a += b
} type LessAdder interface {
 Less(b Integer) bool
 Add(b Integer)
} var a Integer = 1
var b1 LessAdder = &a //OK
var b2 LessAdder = a   //not OK

The assignment of b2 will report a compilation error. Why? Do you remember < Type method > Are the provisions of the Go language specification discussed in chapter 1?

The method set of any other named type T consists of all methods with receiver type T. The method set of the corresponding pointer type T is the set of all methods with receiver T or T (that is, it also contains the method set of T).
That is, *Integer implements all the methods of interface LessAdder, while Integer only implements Less methods, so it cannot be assigned.

(2) by oral assignment


        var r io.Reader = new(os.File)
        var rw io.ReadWriter = r   //not ok         var rw2 io.ReadWriter = new(os.File)
        var r2 io.Reader = rw2    //ok

Because r does not have an Write method, it cannot be assigned to rw.

Nested interface
Let's take a look at another interface in io package:


// ReadWriter is the interface that groups the basic Read and Write methods.
type ReadWriter interface {
 Reader
 Writer
}

The interface is nested between the io.Reader and io.Writer interfaces, which are, in effect, equivalent to the following:


type ReadWriter interface {
Read(p []byte) (n int, err error)
Write(p []byte) (n int, err error)
}

Note that interfaces in the Go language cannot be recursively nested,


// illegal: Bad cannot embed itself
type Bad interface {
 Bad
} // illegal: Bad1 cannot embed itself using Bad2
type Bad1 interface {
 Bad2
}
type Bad2 interface {
 Bad1
}

Empty interface (empty interface)
The empty interface is special in that it does not contain any methods:

interface{}

In the Go language, all other data types implement empty interfaces.


var v1 interface{} = 1
var v2 interface{} = "abc"
var v3 interface{} = struct{ X int }{1}

If the function intends to receive any data type, you can declare the reference as interface{}. The most typical example is the Print and Fprint family of functions in the standard library fmt package:


func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{})
func Fprintln(w io.Writer, a ...interface{})
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{})
func Println(a ...interface{}) (n int, err error)

Note that []T cannot be directly assigned to []interface{}


        t := []int{1, 2, 3, 4}
        var s []interface{} = t

The following error is output at compile time:

cannot use t (type []int) as type []interface {} in assignment

We must do this by:


t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))
for i, v := range t {
    s[i] = v
}


Related articles: