Go language interface details

Time:2022-5-6
catalogue
  • 1. Purpose of interface
  • 2. Type assertion
  • 3. Type selection
  • 4. Empty interface
  • 5. Anonymous empty interface
  • 6. Implement multiple interfaces
  • 7. Interface nesting
  • 8. Interface zero value
  • 9. The difference between make and new
  • summary

An interface is a collection of methods (canonical behavior)

In the field of object-oriented, interfaces are generally defined as follows: interfaces define the behavior of an object and standardize the behavior of subclass objects.

The interfaces in go language are non intrusive (if the interface is gone, the code will not be affected), intrusive (if the interface is gone, the subclass will report an error)

Go is also a duck type. For example, I now have a duck class with speak and run methods. As long as the subclass implements speak and run, I think the subclass is a duck. As long as I have these two methods in the subclass, you are a duck. With these two methods, you are a duck. It derives from bottom to top. As long as you have something in it, you inherit your interface

1. Purpose of interface

Interface is a type

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//Duck defines a duck interface
type Duck interface {
   speak()
   run()
}
 
//Whiteduck defines a white duck structure
type WhiteDuck struct {
   name  string
   age int
   sex string
}
 
//Blackduck defines a black duck structure
type BlackDuck struct {
   name  string
   age int
   sex string
}
 
//Let the white duck and the black duck bind all the methods in the interface, which is called implementing the interface
//Let the white duck implement the duck interface
func (w WhiteDuck) speak() {
   fmt. "Name of the duck, name of the duck, name of the duck"
}
 
func (w WhiteDuck) run() {
   fmt. Println ("white duck walks slowly, its name is" w.name ")
}
 
//Let the black duck implement the duck interface
func (b BlackDuck) speak() {
   fmt. Println ("black duck quacks, its name is", b.name)
}
 
func (b BlackDuck) run() {
   fmt. Println ("the black duck walks awkwardly, its name is", b.name)
}
 
 
func main() {
   var duck Duck
   Duck = whiteduck {"Xiaobai", 15, "male"} // assign my object to an interface type to achieve the effect of polymorphism
   fmt.Println(duck)
    
   //Duck is now an interface. It can only take methods, not properties.
   duck.speak()
   duck.run()
}

//Output:
{Xiaobai 15 male}
The white duck quacks. Its name is Xiaobai
The white duck walks slowly. Its name is Xiaobai

2. Type assertion

It is used to extract the underlying value of the interface, that is, to convert the interface type into struct, properties, and its own methods.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func main() {
    Var duck duck = whiteduck {"little white", 15, "male"}
    //Assertion is of type whiteduck
    value, ok := duck.(WhiteDuck)
    //The assertion is successful, OK = true, and value is the whiteduck structure object
    fmt. Println (value) // output: {Xiaobai 15 male}
    fmt. Println (value. Name) // output: Xiaobai
    fmt. Println (OK) // output: true
 
    //Assertion failed, OK1 = false, value1 is a null value of blackduck type because there is no assignment
    value1, ok1 := duck.(BlackDuck)
    fmt. Println (value1) // output: {0}
    fmt. Println (OK1) // output: false
}

3. Type selection

(via type switch)

It is used to compare the specific type of the interface with the type specified by many case statements.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func main() {
   Var duck duck = whiteduck {"little white", 15, "male"}
   test(duck)
}
 
func test(duck Duck) {
   switch value := duck.(type) {
   case WhiteDuck:
      fmt.Println(value.name)
      fmt. Println ("I'm a white duck")
   case BlackDuck:
      fmt.Println(value.name)
      fmt. Println ("I'm a black duck")
   default:
      fmt.Println(value)
      fmt. Println ("I'm a duck")
   }
}

4. Empty interface

Without any method, all data types implement empty interfaces

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Type empty interface {} // empty interface
 
func main() {
   var a int = 10
   var b string = "XiaoYang"
   var c [3]int
   Var e empty // E is an empty interface type and can accept any data type
   e = a
   e = b
   e = c
    
   //In this case, you need to choose its type back
   //Normally, I can only receive empty type, but a, B and C are not empty type
   Test (a) // output: I am int 10
   Test (b) // output: I am Xiaoyang
   Test (c) // output: I am an array [0]
}
 
//If this is not an empty interface, such as duck, all data types that implement the duck interface can be passed
func test(b Empty)  {      
   switch v:=b.(type) {
   case string:
      fmt. Println ("I am a string", V)
   case int:
      fmt. Println ("I'm int", V)
   case [3]int:
      fmt. Println ("I'm an array", V)
   }
}

5. Anonymous empty interface

An empty interface without a name is usually used for formal parameters

?
1
2
3
4
5
6
7
8
9
10
11
func main() {
   Var duck duck = whiteduck {"little white", 15, "male"}
   test(10)
   test("XiaoYang")
   test(duck)
}
 
//This is called anonymous empty interface. All data types can be transferred to it. If you want to use the original structure, you need to select the type back to use it
func test(b interface{}) {
   fmt.Println(b)
}

6. Implement multiple interfaces

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//Duck defines a duck interface
type Duck interface {
   speak()
   run()
}
 
type Animal interface {
   eat()
   sleep()
}
 
//Whiteduck defines a white duck structure
type WhiteDuck struct {
   name string
   age  int
   sex  string
}
 
 
//Let the white duck implement both the duck interface and the animal interface
func (w WhiteDuck) speak() {
   fmt. "Name of the duck, name of the duck, name of the duck"
}
 
func (w WhiteDuck) run() {
   fmt. Println ("white duck walks slowly, its name is" w.name ")
}
 
func (w WhiteDuck) eat() {
   fmt. Println ("white duck eats, its name is", w.name)
}
 
func (w WhiteDuck) sleep() {
   fmt. Println ("white duck sleeps, its name is", w.name)
}
 
 
func main() {
    var w WhiteDuck = WhiteDuck{}
    var a Animal
    var d Duck
 
    //In this way, my w can be given to both a and D
    //However, once you switch to an interface, you can only use the methods of the interface. Your own attributes and methods can only be used after type assertion
    
    A = w // if w gives a, a can only call the methods of the animal interface
    a.sleep()
    a.eat()
    
    D = w // if w gives D, a can only call the methods of the duck interface
    d.run()
    d.speak()
}

7. Interface nesting

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
type Duck interface {
   Animal // duck nested interface
   speak()
   run()
}
 
type Animal interface {
   eat()
   sleep()
}
 
type WhiteDuck struct {
   name string
   age  int
   sex  string
}
 
 
//In this way, the white duck implements both the duck interface and the animal interface
func (w WhiteDuck) speak() {
   fmt. "Name of the duck, name of the duck, name of the duck"
}
 
func (w WhiteDuck) run() {
   fmt. Println ("white duck walks slowly, its name is" w.name ")
}
func (w WhiteDuck) eat() {
   fmt. "Name of the duck, name of the duck, name of the duck"
}
 
func (w WhiteDuck) sleep() {
   fmt. Println ("white duck walks slowly, its name is" w.name ")
}
 
 
 
func main() {
   var a Animal
   var d Duck
   var w WhiteDuck = WhiteDuck{}
 
   //W can be given either a or D
   A = w // but a can only call two methods in animal
   a.sleep()
   a.eat()
 
   D = w // D can call four methods in duck and animal
   d.sleep()
   d.eat()
   d.speak()
   d.run()
}

8. Interface zero value

?
1
2
3
4
5
6
7
func main() {
 
   Var a animal // nil indicates that it is a reference type
   //Its internal representation has told us that there are two values in it, one is its type, and the other is a pointer to a specific value
 
   fmt. Println (a) // output: < nil >
}

9. The difference between make and new

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
type WhiteDuck struct {
   name string
   sex  string
   age  int
}
 
func main() {
   Var Per1 * whiteduck = new (whiteduck) // new is the return pointer to this type
   //Or I take the address of whiteduck and assign it to per2
   var per2 = &WhiteDuck{}
 
   fmt. Println (Per1) // output: & {0}
   fmt. Println (per2) // output: & {0}
 
   Var PER3 = make ([] int, 3, 4) // make is the specific reference type created
                           //New is to create a pointer to this type
   Var per4 = new ([] int) // is a pointer to the slice type
 
   fmt. Println (PER3) // output: [0]
   fmt. Println (per4) // output: & []
}

summary

That’s all for this article. I hope it can help you, and I hope you can pay more attention to more content of developeppaper!