Go语言中interface接口

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package main

import "fmt"

//接口是一种类型 一种抽象的类型
//面向接口编程
//语法

//type 接口类型名 interface {
// 方法名1(参数列表1) 返回值列表1
// 方法名1(参数列表1) 返回值列表1
//}

//接口类型名 一般在后门加er 如Writer Singer
//接口类型名、方法名 首字母大写时,对外可见
//参数列表、返回列表中参数变量名可以省略 只需写类型

type Sayer interface {
say()
}

type dog struct {

}

type cat struct {

}

func (d dog) say() {
fmt.Println("汪汪汪")
}

func (c cat) say() {
fmt.Println("喵喵喵")
}

type Mover interface {
move()
}

//值接收者实现接口
//此时实现接口是dog类型
//func (d dog) move() {
// fmt.Println("狗会动~")
//}

//指针类型接收者实现接口
func (d *dog) move() {
fmt.Println("狗会动~")
}

//接口嵌套
type Animaler interface {
Sayer
Mover
}

type cat2 struct {
name string
}

func (c cat2) say() {
fmt.Println("喵喵喵")
}

func (c cat2) move() {
fmt.Println("猫会动")
}

func main() {
//var x Sayer
//a := dog{}
//b := cat{}
//x =a
//x.say()
//x = b
//x.say()

//var xx Mover
//wangcai := dog{}
//xx = wangcai 不能接收dog值类型
//xx.move()
//fugui := &dog{}
//xx = fugui
//xx.move()
//不管dog结构体还是结构体指针*dog类型的变量 都可以赋值给Mover接口变量
//go语言语法糖对指针变量取值会自动加*fugui

//一个类型可以实现多个接口
//多个类型可以实现一个接口

var x Animaler
x = cat2{name:"耳朵"}
x.say()
x.move()
}

// 接口应用

package main

import "fmt"

//空接口
// 没有定义任何方法的接口
// 也就是说任意类型都可以实现空接口
//换言之空接口类型的变量可以存储任意类型的变量

//定义x 空接口 比较繁琐
//type x interface {}


func Show(a interface{}) {
fmt.Printf("Type: %T Value: %v\n",a, a)
}

func main() {
//通常通过以下语法定义空接口
//var x interface{}
//s := "人才牛"
//x = s
//fmt.Printf("Type: %T Value: %v\n",x, x)
//i := 200
//x = i
//fmt.Printf("Type: %T Value: %v\n",x, x)
//b := true
//x = b
//fmt.Printf("Type: %T Value: %v\n",x, x)

//空接口应用
//作为函数传参 空接口作为函数参数 可以接收任意类型变量
//x := 666
//Show(x)
//y := "Pengge 666"
//Show(y)

//空接口可以作为mao的值
//var studentInfo = make(map[string]interface{})
//studentInfo["name"] = "Ropon"
//studentInfo["age"] = 18
//studentInfo["status"] = true
//fmt.Println(studentInfo)
//fmt.Printf("%#v", studentInfo)
//
//var testInfo = make(map[interface{}]interface{})
//testInfo[11] = 23
//testInfo["niubi"] = true
//testInfo["arg"] = "lihaile"
//fmt.Println(testInfo)
//fmt.Printf("%#v", testInfo)

//类型断言
//语法
//x.(T) x 表示类型为interface{}的变量 T 表示要断言的类型
//返回两个参数 第一个参数是x转化为T类型后的变量 第二参数是布尔值 true表示断言成功,否则断言失败
//var x interface{}
//x = "haolihaio"
//v, ok := x.(string)
//if ok {
// fmt.Println(v)
//} else {
// fmt.Println("类型断言失败")
//}

//switch
var x interface{}
//x = "niubi"
x = 11
//x = true
switch v := x.(type) {
case string:
fmt.Printf("x is a string value is %v\n", v)
case int:
fmt.Printf("x is a int value is %v\n", v)
case bool:
fmt.Printf("x is a bool value is %v\n", v)
}
}