服务器之家

服务器之家 > 正文

详解Golang语言中的interface

时间:2021-03-24 00:50     来源/作者:雨燕

interface是一组method签名的组合,interface可以被任意对象实现,一个对象也可以实现多个interface。任意类型都实现了空interface(也就是包含0个method的interface),空interface可以存储任意类型的值。interface定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。

go version go1.12

?
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main
 
import (
  "fmt"
)
 
// 定义struct
type Human struct {
  name string
  age  int
  phone string
}
type Student struct {
  Human // 匿名字段
  school string
  loan  float32
}
type Employee struct {
  Human  // 匿名字段
  company string
  money  float32
}
 
// Human对象实现SayHi()方法
func (h Human) SayHi() {
  fmt.Printf("Hi, I am %s, you can call me on %s\n", h.name, h.phone)
}
 
// Human对象实现Sing()方法
func (h Human) Sing(lyrics string) {
  fmt.Println("La la la...", lyrics)
}
 
// Human对象实现Guzzle()方法
func (h Human) Guzzle(beerStein string) {
  fmt.Println("Guzzle Guzzle Guzzle...", beerStein)
}
 
// Employee对象重写SayHi()方法
func (e Employee) SayHi() {
  fmt.Printf("Hi I am %s, I work at %s. Call me on %s\n", e.name, e.company, e.phone)
}
 
// Student对象实现BorrowMoney()方法
func (s Student) BorrowMoney(amount float32) {
  s.loan += amount
}
 
// Employee对象实现SpendSalary()方法
func (e Employee) SpendSalary(amount float32) {
  e.money -= amount
}
 
// 定义interface,interface是一组method签名的组合
// interface可以被任意对象实现,一个对象也可以实现多个interface
// 任意类型都实现了空interface(也就是包含0个method的interface)
// 空interface可以存储任意类型的值
// interface Men的3个method被Human,Student,Employee实现,也就是这3个对象都实现了interface Men。即:
// interface定义了一组方法,如果某个对象实现了某个接口的所有方法,则此对象就实现了此接口。
type Men interface {
  SayHi()
  Sing(lyrice string)
  Guzzle(beerStein string)
}
 
// interface YoungChap的BorrowMoney() method只被Student对象实现,也就是只有Student实现了YoungChap
type YoungChap interface {
  SayHi()
  Sing(song string)
  BorrowMoney(amount float32)
}
 
// interface ElderlyGent的SpendSalary() method只被Employee对象实现,也就是只有Employee实现了ElderlyGent
type ElderlyGent interface {
  SayHi()
  Sing(song string)
  SpendSalary(amount float32)
}
 
func main() {
  // 定义Student类型的变量
  lucy := Student{Human{"lucy", 19, "10086"}, "tsinghua", 100.00}
  lily := Student{Human{"lily", 19, "10086"}, "tsinghua", 100.00}
  liming := Student{Human{"liming", 19, "10086"}, "tsinghua", 100.00}
  // 定义Employee类型的变量
  tom := Employee{Human{"tom", 29, "10000"}, "Google", 200.00}
  // 定义Men类型的变量i
  var i Men
  // i存储Student
  i = lucy
  fmt.Println("This is lucy, a student:")
  i.SayHi()
  i.Sing("Happy Birthday")
  i.Guzzle("Ha ha ha...")
 
  // i存储Employee
  i = tom
  fmt.Println("This is tom, an Employee:")
  i.SayHi()
 
  // 定义slice Men,包含Men类型元素的切片,这个slice可以被赋予实现了Men接口的任意结构的对象
  fmt.Println("Let's use a slice of Men and see what happens:")
  x := make([]Men, 3)
  // 三个不同类型(不同Method)的元素,实现了同一个interface(Men)
  x[0], x[1], x[2] = lucy, lily, liming
  for _, value := range x {
    value.SayHi()
  }
}

函数参数

interface接口还可以作为函数参数,因为interface的变量可以持有任意实现该interface类型的对象,我们可以通过定义interface参数,让函数接受各种类型的参数。 判断interface变量存储的元素的类型,目前常用的有两种方法:Comma-ok断言和switch测试。

go version go1.12

?
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/**
 * interface接口作为函数参数
 * 判断interface变量存储的元素的类型
 */
package main
 
import (
  "fmt"
  "strconv"
)
 
// 定义Human对象
type Human struct {
  name string
  age  int
  phone string
}
 
// 定义空接口
type Element interface{}
 
// 定义切片
type List []Element
 
// 定义Person对象
type Person struct {
  name string
  age int
}
 
// 通过定义interface参数,让函数接受各种类型的参数
// 通过这个Method(方法),Human对象实现了fmt.Stringer接口
// Stringer接口是fmt.Println()的参数,最终使得Human对象可以作为fmt.Println的参数被调用
func (h Human) String() string {
  return "<" + h.name + " - " + strconv.Itoa(h.age) + " years - phone: " + h.phone + ">"
}
 
// 通过定义interface参数,让函数接受各种类型的参数
// 通过这个Method(方法),Person对象实现了fmt.Stringer接口
// Stringer接口是fmt.Println()的参数,最终使得Person对象可以作为fmt.Println的参数被调用
func (p Person) String() string {
  return "(name: " + p.name + " - age: " + strconv.Itoa(p.age) + " years)"
}
 
func main() {
  // interface作为函数的参数传递
  Lucy := Human{"Lucy", 29, "10086"}
  fmt.Println("This human is:", Lucy)
 
  list := make(List, 3)
  list[0] = 100
  list[1] = "Hello Golang!"
  list[2] = Person{"Lily", 19}
 
  // Comma-ok断言
  for index, element := range list {
    // 判断变量的类型 格式:value, ok = element(T)
    // value是interface变量的值,ok是bool类型,element是interface的变量,T是断言的interface变量的类型
    if value, ok := element.(int); ok {
      fmt.Printf("list[%d] is an int and it's value is %d\n", index, value)
    } else if value, ok := element.(string); ok {
      fmt.Printf("list[%d] is a string and it's value is %s\n", index, value)
    } else if value, ok := element.(Person); ok {
      fmt.Printf("list[%d] is a Person and it's value is %s\n", index, value)
    } else {
      fmt.Printf("list[%d] is a different type\n", index)
    }
  }
 
  // switch
  for index, element := range list {
    // 注意:element.(type)语法不能在switch外的任何逻辑中使用
    switch value := element.(type) {
    case int:
      fmt.Printf("list[%d] is an int, it's value is %d\n", index, value)
    case string:
      fmt.Printf("list[%d] is a string, it's value is %s\n", index, value)
    case Person:
      fmt.Printf("list[%d] is a Person, it's value is %s\n", index, value)
    default:
      fmt.Printf("list[%d] is a differernt type", index)
    }
  }
}

以上就是详解Golang语言中的interface的详细内容,更多关于Golang语言中的interface的资料请关注服务器之家其它相关文章!

原文链接:https://cnswift.cn/posts/Go/golang-interface-1.html

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
返回顶部