Interface interface
Interface is a kind of constraint that both callers and implementers need to abide by. It restricts developers to deal with specific business according to unified method naming, parameter type and quantity. In fact, an interface is a group of method declarations that are not implemented. When a user-defined type wants to use this method, these methods will be implemented according to the specific situation. Interface syntax:
type Interface type name interface { Method name 1(parameter list) Return value list Method name 2(parameter list) Return value list ... }
Example:
package main import "fmt" // type of shipping type Transporter interface { BicycleTran() CarTran() } // driver type Driver struct { Name string Age int } // Implement transportation mode interface func (d *Driver) BicycleTran() { fmt.Println("Transport by bicycle") } func (d *Driver) CarTran() { fmt.Println("Transport by car") } func main() { d := &Driver{ "Zhang San", 27, } trans(d) } // As long as the Transporter interface is implemented, the type can be used as a parameter func trans(t Transporter) { t.BicycleTran() }
be careful:
- When naming the interface of Go language, er is usually added after the word. For example, the interface for write operation is called Writer
- When the method name is capitalized and the implemented interface is capitalized, the method can be accessed by code outside the package where the interface is located
- Method and method signature in the interface are consistent (method name, parameter list and return list must be consistent)
- The variable names in the parameter list and return value list can be ignored, such as: type writer interfae {write ([] byte) error}
- All methods in the interface must be implemented
- If the method signatures implementing the interface are found to be inconsistent during compilation, an error will be reported: does not implement.
II. Characteristics of Go interface
In the above example, Go does not need to explicitly declare which interface is implemented like Java, that is, it is non intrusive. The interface writer does not need to know which type of interface is implemented. The interface implementer only needs to know what kind of interface is implemented, but does not need to indicate which interface is implemented. The compiler knows which type is used to implement which interface in the final compilation, or who should implement the interface.
There are one to many and many to one relationships between types and interfaces, namely:
- A type can implement multiple interfaces, which are independent of each other and do not know each other's implementation
- Multiple types can also implement the same interface.
type Service interface { Start() Log(string) } // Logger type Logger struct { } //Log output method func (g *Logger) Log(s string){ fmt.Println("journal:", s) } // Game services type GameService struct { Logger } // Method for realizing game service func (g *GameService) Start() { fmt.Println("Game service startup") } func main() { s := new(GameService) s.Start() s.Log("hello") }
In the above case, it can run even without an interface, but when there is an interface, it will implicitly implement the interface and let the interface provide constraints to the class.
Using the interface to call the methods in the structure can also be understood as realizing polymorphism in object-oriented.
Three interface nesting
In Go, not only structures can be nested, but also interfaces can be nested. Interface and interface nesting form a new interface. As long as all methods of the interface are implemented, the methods of all nested interfaces in the interface can be called.
// Define a write interface type Writer interface { Write(p []byte) (n int, e error) } // Define a read interface type Reader interface { Read() error } // Define a nested interface type IO interface { Writer Closer }
Four air interface
4.1 definition of empty interface
Empty interface is a special form of interface without any method, so any specific type can be considered to implement empty interface.
var any interface{} any = 1 fmt.Println(any) any = "hello" fmt.Println(any)
Empty interface as function parameter:
func Test(i interface{}) { fmt.Printf("%T\n", i) } func main() { Test(3) // int Test("hello") // sting }
Using the empty interface, any type of storage can be realized:
m := make(map[string]interface{}) m["name"] = "Li Si" m["age"] = 30
4.2 get value from empty interface
For the value saved to the empty interface, if the value of the specified type is directly taken out, a compilation error will occur:
var a int = 1 var i interface{} = a var b int = i //Here, the compiler reports an error (inconsistent type). You can do this: B: = I
4.3 empty interface value comparison
Comparison of empty interfaces of different types:
var a interface{} = 100 var b interface{} = "hi" fmt.Println(a == b) //false
Cannot compare dynamic values in an empty interface:
var c interface{} = []int{10} var d interface{} = []int{20} fmt.Println(c == d) //Operation error
Type and comparability of empty interface:
type | explain |
---|---|
map | Incomparable, downtime errors occur |
section | Incomparable, downtime errors occur |
passageway | Comparable, it must be generated by the same make, that is, the same channel is true |
array | It can be compared, and whether it is consistent can be known at the compilation time |
structural morphology | The value of a comparable structure |
function | Comparable |