From:https://www.cnblogs.com/mike-zh/p/3787679.html
Simply put, interface is a set of method combinations that can be interface to define a set of behaviors for an object.
If an object implements all the methods of an interface, it means that it implements the pretext without explicitly adding an interface description to the type.
Interface is a collection of methods in which there are no other types of variables, and method is not implemented with a defined prototype
① Interface Definition
1. Naming is used to end with "ER", such as printer Reader Writer
2. A interface method should not be too much, generally 0~3 a
3. A interface can be arbitrarily subject matter; Correspondingly, an object can also implement multiple interface
Example:
Type peoplestruct{
Name string}
Type Student struct{
People
School string}
Type Teacher struct{
People
Department string}
Func (P people) Sayhi () {}
Func (S Student) Sayhi () {}
Func (t Teacher) Sayhi () {}
Func (S Student) Study () {}//extracts the interface according to the method of the struct so that the struct automatically implements the interface type speakerinterface{
Sayhi ()
}
Type Learner interface{
Sayhi ()
Study ()
}
In the above example, the Speaker interface is implemented by the object people,teacher,student, while the student implements both the interface speaker and the learner.
Interface combination:
Type Speaklearnerinterface {
Speaker
Learner
}//combination makes the Speaklearner function with speaker and learner
Null interface:
Any type implements an empty interface, which is equivalent to the object class in Java
Func Test (ainterface{}) {}//The method can accept any type (int rune float32 struct ... ) Parameters of
② interface execution mechanism and interface assignment
First, a function mechanism of the Go Language band receiver (receiver) is introduced (the following two cases execute the same result, which is still the same when the struct member value is changed)
Scenario 1:
Package Main
Import (
"FMT")
Type people struct {
Name string}
Func (P people) Sayhi () {//receiver is strcutfmt.println here ("Hello, this is", p.name)
}
Func (P *people) Study () {//receiver here is ****structfmt. Printf ("%s is studying\n", p.name)
}
Type Speaklearner Interface {
Sayhi ()
Study ()
}
Func Main () {
People: = people{"Zhangsan"}//here people for people type people. Sayhi ()
People. Study ()
}
Scenario 2:
Func Main () {
People: = &people{"Zhangsan"}//here people is the **people type, which is the pointer people. Sayhi ()
People. Study ()
}
The above example shows that the functions of receiver people and *people can be called by people or *people two types, followed by the possibility of conversion between people and *people during invocation.
Look at the following example:
Package Main
Import (
"FMT")
Type Example struct{
Integer1 int Integer2 int}
Func (e Example) Assign (num1 int, num2int) {
E.integer1, E.integer2 = NUM1, num2
}
Func (e *example) Add (Num1int, Num2int) {
E.integer1 +=NUM1
E.integer2 +=num2
}
Func Main () {
Vare1 Example = example{3,4}
E1. Assign (a)
Fmt. PRINTLN (E1)
E1. ADD (+)
Fmt. PRINTLN (E1)
Vare2 *example = &example{3,4}
E2. Assign (a)
Fmt. PRINTLN (E2)
E2. ADD (+)
Fmt. PRINTLN (E2)
}
The results of the above procedure are as follow:
{3,4}
{4,5}&{3,4}&{4,5}
You can see that the actual execution of the procedure is performed by the receiver type before the function definition.
For the execution mechanism of the interface:
1.T only has a set of methods that belong to the type T, while *t owns the (t+*t) method set
2. Based on the T implementation method, means that the interface and interface (*T) interfaces are implemented simultaneously
3. Based on the *t implementation method, it is only possible to implement interface to interface (*T)
Type Integerintfunc (a integer) less (b integer) bool {
Returna < b
}
Func (a *integer) Add (b Integer) {
*a + = b
}
Accordingly, we define the interface Lessadder as follows:
Type Lessadder Interface {
Less (b integer) bool Add (b Integer)
}
Now there is a problem: Suppose we define an object instance of an integer type, how can we assign it to the Lessadder interface?
Should I use the following statement (1) or a statement (2)? Vara Integer =1varb lessadder = &a ... (1) Varb Lessadder = a ... (2)
The answer is that the statement (1) should be used. The reason is that the go language can be based on the following function:
Func (a integer) less (b integer) bool
A new less () method is automatically generated:
Func (a *integer) less (b Integer) bool {
Return (*A). Less (b)
}
Thus, the type *integer has both the less () method and the Add () method, which satisfies the Lessadder interface.
And on the other hand, according to
Func (a *integer) Add (b Integer)
This function cannot automatically generate the following member method:
Func (a integer) Add (b integer) {
(&a). ADD (b)
}
Because (&a). ADD () changes the function parameter a only, does not have the influence to the outside actually to manipulate the object, this does not match the combination
The user's expectations. Therefore, the go language does not automatically generate this function for it.
Therefore, the type integer only has the less () method, the Add () method is missing, and the Lessadder interface is not satisfied, therefore the above statement (2) cannot be assigned a value.
Examples of interface assignment:
Package Main
Import
"FMT")//define objects people, teacher, and Studenttype peoplestruct {
Name string}
Type Teacher struct{
People
Department string}
Type Student struct{
People
The School string}//object method implements Func (P people) sayhi () {
Fmt. Printf ("Hi, I ' m%s. Nice to meet you!\n", p.name)
}
Func (t Teacher) Sayhi () {
Fmt. Printf ("Hi, my name is%s. I ' m working in%s. \ n ", T.name, T.department)
}
Func (S Student) Sayhi () {
Fmt. Printf ("Hi, my name is%s. I ' m studying in%s.\n ", S.name, S.school)
}
Func (S Student) Study () {
Fmt. Printf ("I ' m learning Golang in%s.\n", S.school)
}//defining interfaces speaker and Learnertype speakerinterface{
Sayhi ()
}
Type Learner interface{
Sayhi ()
Study ()
}
Func Main () {
People: = people{"Zhang San"}
Teacher: = teacher{people{"Zheng Zhi"}, "Computer Science"}
Student: = student{people{"Li Ming"}, "Yale University"}
varisspeaker//defines speaker interface type variables is= people//is can store Peopleis.sayhi ()
is= teacher//is can store Teacheris.sayhi ()
is= Student
Is. Sayhi ()//is can store studentvar il learner
Il = student//learner variable of type interface can store student IL. Study ()
}
The result of the execution is:
Hi, I ' m Zhang three. Nice to meet you! Hi, my Nameis zheng Zhi. I ' m working in computer. Hi, my Nameis Li Ming. I ' m studying in Yale university.i ' m learning Golang in Yale University.
This example allows you to see the important role of interface mechanisms in polymorphism and the creation of extensible reusable code, as in Java and other languages.
③ anonymous fields and interface conversions
If the interface type S is internally embedded with the interface type T (anonymous), then the interface anonymous field method set rules are as follows:
1. If s embeds an anonymous type T, the S method set contains the set of T methods.
2. If s embeds an anonymous type *t, the S method set contains the *t method set (including methods Riceiver T and *t).
3. If s embeds an anonymous type T or *t, then the *s method set contains the *t method set (including methods for Riceiver T and *t). Important
For example:
Package Main
Import
"FMT"
)
Type people struct {
Name string}
Type S1 struct{
People//s1 type embedded anonymous peopledepartmentstring}
Type S2 struct{
*PEOPLE//S2 type embedding anonymous *peopledepartmentstring}
Func (P people) Say1 () {
Fmt. Printf ("Hi, I ' m%s. say1111\n", P.name)
}
Func (P *people) Say2 () {
Fmt. Printf ("Hi, I ' m%s. say2222\n", P.name)
}
Type Speaker interface{
Say1 ()
Say2 ()
}
Func Main () {
People: = people{"Zhang San"}
S1: = s1{people{"Zheng Zhi"}, "Computer Science"}
S2: = s2{&people{"Li Ming"}, "Math"}
Varis Speaker
Is= &people//*people implements the Speaker interface Is.say1 ()
Is. Say2 ()
is = S1//s1 type embedded anonymous people does not exist Say2 () method thus does not implement Speaker interface
Error hint: cannot use S1 (type S1) as type Speaker in assignment:
S1 does not implement Speaker (Say2 method have pointer receiver) is= S2//S2 type embedded anonymous *people thus (P people) Say1 () and (P *people) The Say2 () method has implemented the Speaker interface Is.say1 ()
Is. Say2 ()
is= &s1//s1 type embedded in anonymous people *S1 implements Speaker interface Is.say1 ()
Is. Say2 ()
is= &s2//s2 type embedded in anonymous *people *S2 implements Speaker Interface Is.say1 ()
Is. Say2 ()
}
The result of the execution is:
Hi, I ' m Zhang three. Say1111hi, I ' m Zhang three. Say2222hi, I ' m Li Ming. Say1111hi, I ' m Li Ming. Say2222hi, I ' m Zheng Zhi. Say1111hi, I ' m Zheng Zhi. Say2222hi, I ' m Li Ming. Say1111hi, I ' m Li Ming. Say2222
This proves the 3 rules of the Anonymous field method set.
Interface conversions are analogous to the interface inheritance rules that can be thought of as implementations of complex interfaces (methods) to simple interfaces (fewer methods), where methods in simple interfaces are declared in complex interfaces. For example:
Package Main
Import
"FMT")
Type people struct {
Name string}
Type Student struct{
People
School string}
Func (P people) getpeopleinfo () {
Fmt. PRINTLN (P)
}
Func (S Student) Getstudentinfo () {
Fmt. PRINTLN (s)
}
Type Peopleinfo interface{
Getpeopleinfo ()
}
Type Studentinfo interface{
Getpeopleinfo ()
Getstudentinfo ()
}
Func Main () {
Varisstudentinfo = student{people{"Li Ming"}, "Yele University"}
Is. Getstudentinfo ()
Is. Getpeopleinfo ()
Varip peopleinfo =is IP. Getpeopleinfo ()
Ip. Getstudentinfo () Note:ip. Getstudentinfo undefined}
④ interface type inference: COMMA-OK assertions and switch tests
Using interface type inference, you can reverse-understand which type of object is actually stored in the interface type variable.
In the go language, there are two common methods for interface type inference, namely, COMMA-OK assertions and switch tests
COMMA-OK assertions use the following format
Value,ok = element. T
Usage examples:
Using COMMA-OK assertions for Interface type inference package main
Import
"FMT")
Type People struct{
Name string Age int}//defines an empty interface for storing any type of data type objectinterface{}
Func Main () {
People: = people{"Zhang San", 20}
OBJS: = make ([]object,4)
Objs[0], objs[1], objs[2], objs[3] =1,true, "Hello", people
Forindex, element: = Range objs{
Ifvalue, OK: = element. (int); ok{
Fmt. Printf ("objs[%d] type is int,value=%d\n", index, value)
}elseifvalue, OK: = element. (bool); ok{
Fmt. Printf ("objs[%d] type is bool,value=%v\n", index, value)
}elseifvalue, OK: = element. (string); ok{
Fmt. Printf ("objs[%d] type is string,value=%s\n", index, value)
}elseifvalue, OK: = element. (people); ok{
Fmt. Printf ("objs[%d] type is peole,value=%v\n", index, value)
}else{
Fmt. Printf ("objs[%d] type unknown \ n", index)
}
}
}
The result is this:
Objs[0] Type is int,value=1objs[1] type is bool,value=trueobjs[2] type is String,value=hello
OBJS[3] Type is peole,value={320}
Using the switch test to determine the interface type, the program structure is more concise, the example is as follows (only the main function in the example is modified):
Func Main () {
People: = people{"Zhang San", 20}
OBJS: = make ([]object,4)
Objs[0], objs[1], objs[2], objs[3] =1,true, "Hello", people
Forindex, element: = Range objs{
Switchvalue: = element. (type) {
Caseint:
Fmt. Printf ("objs[%d] type is int,value=%d\n", index, value)
Casebool:
Fmt. Printf ("objs[%d] type is bool,value=%v\n", index, value)
Casestring:
Fmt. Printf ("objs[%d] type is string,value=%s\n", index, value)
Case people:
Fmt. Printf ("objs[%d] type is peole,value=%v\n", index, value)
Default
Fmt. Printf ("objs[%d] type unknown \ n", index)
}
}
}