Understanding interface key points in Go
Interface is the essence of Golang, this paper mainly understand several key points in interface.
Interface is a collection of method and a type
- The basic function of the existence of interface is that it defines a set of methods.
We say that interface is a type that can be understood from three points: first, it can be seen from the type keyword in its definition form. In addition, the formal parameters of the function can be interface type; Finally, interface supports the polymorphism in go, that is, if all the methods in interface are implemented, the type implements the interface, which is similar to inheritance in C + +.
type Inter interface { Get() int Set(int)}
- Go allows interface without any method, this type is called empty interface, because it does not take any method, so it can be said that all types have implemented the empty interface.
The interface variable stores the value of the implementation type
- Because only methods exist in interface, the formal parameters of a method come from its implementation type.
package main import "fmt"type Inter interface { Get() int Set(int)}type St struct { Age int }func(s St) Get() int { return s.Age} func(s *St) Set(age int) { s.Age = age }func test(i Inter) { i.Set(10) fmt.Println(i.Get())}func main() { s := St{} test(&s)}
In this code, ST implements the Inter, executes test (), and completes the use of the Inter.
- One of the important uses of interface is in the parameters of the test function, and if more than one type implements interface, these types of values can be stored directly using the interface variable.
s := S{}var i Interi = &sfmt.Println(i.Get()) //会自动调用S中关于Get的实现
This also shows the polymorphism of Go.
Empty interface
- Empty interface have no method, so all types implement the empty interface, so all types can be the parameters of the empty interface function:
func doSomething(v interface{}) {}
Since the empty interface can accept any type of argument, is the slice of a interface{} type acceptable to any type of slice? --No!
package main import "fmt"func printAll(vals []interface{}) { for _, val := range vals { fmt.Println(val) }}func main() { names := []string{"hello", "world"} printAll(names)}
Execution Result:
This example shows that go cannot convert slice to interface{} type slice, but we can convert it manually:
var interfaceSlice []interface{} = make([]interface{}, len(names)) for i,d := range names { interfaceSlice[i] = d }
Execution Result:
Receiver's understanding
- The parameters in Func () in the method that defines the struct in go are called receiver. For example, the S in func (S St) get () int {} is the receiver of get. To understand that he can associate the this pointer in C + +.
- We call the test function in the example above as test (&s), which is the pointer type of St, can it be test (s)?
The execution result of the call to test (s) is as follows:
This is a wrong implementation, and the key is that the receiver of the set () method in St is a pointer *st.
Interface is not defined as a method of being idle. Receiver is value receiver or pointer receiver, as in the example above, when we use Test (s) as the form of invocation, passed to test is a copy of S, When a copy of S is made to the Inter, receiver of the s copy of the Slow set () method is a pointer, which is not implemented.
If, in turn, receiver is value, the function is called in the form of pointer:
package main import "fmt"type Inter interface { Get() int Set(int)}type St struct { Age int }func(s St) Get() int { return s.Age} func(s St) Set(age int) { s.Age = age }func test(i Inter) { i.Set(10) fmt.Println(i.Get())}func main() { s := St{} test(&s) test(s)}
The result of the execution is:
The reason why we failed to output 10 10 according to our expectations is that the value of the original data cannot be changed. But the code is functioning properly, that is to say receiver is the value receiver, execution code whether pointer or value can be executed normally.
What is the reason for this phenomenon?
If the incoming pointer,go can find the corresponding value according to pointer, but if it is value, only the copy of value can be passed to temp, there is no way to find the original address of value based on the copy temp of value. This is why pointer can correspond to pointer receiver and value receiver, but value does not meet pointer receiver.
In fact, the key point here is that the argument to the formal parameter is just a copy.
Image