13、interface
接口(interface)定义了一个对象的行为规范,之定义规范不实现。
接口类型
Go语言中接口(interface)是一种类型,一种抽象的类型。
interface
是一组method
的集合,是duck-type programming
的一种体现。接口做的事情就像是定一个协议(规则)。不关心属性(数据),只关心行为方法。
接口的定义
1 | type 接口类型名 interface{ |
其中:
接口名:使用
type
将接口定义为自定义类型名时。Go语言在接口命名时,一般会在单词后面加er
,如有写操作的接口叫做Writer
,有字符串功能的接口叫做stringer
。接口名最好能突出该接口类型的含义。方法名:当方法名首字母是大写并且这个接口类型名首字母也是大写时,这个方法可以被接口所在的包(package)之外的代码当问。
参数列表、返回值列表:参数列表和返回值列表中的参数变量名可以省略。
1
2
3type writer interface{
Writer([]byte) error
}接口实现的条件
一个对象只要实现了接口中的所有方法,那么就实现了这个接口。
1
2
3
4
5//定义接口
type speaker interface {
//接口方法
speak()
}1
2
3
4
5type cat struct{}
func (c cat) speak(){
fmt.Println("喵喵喵~")
}1
2
3
4
5type person struct{}
func (p person) speak(){
fmt.Println("啊啊啊~")
}接口类型变量
1
2
3
4
5
6
7
8
9
10
11
12var speaker speaker
var d dog
var c cat
var p person
speaker = d
speaker.speak()
speaker = c
speaker.speak()
speaker = p
speaker.speak()
值接收者和指针接收者实现接口的区别
值接收者实现接口
因为Go语言中有使用指针类型变量求值的语法糖。
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//值接收者
type animal interface{
move()
eat(string)
}
type cat struct{
name string
feet int64
}
//实现接口
func (c cat) move(){
fmt.Println("走猫步~~")
}
func (c cat) eat(food string){
fmt.Printf("猫吃%s!", food)
}
func main() {
//定义接口变量
var a1 animal
//值类型
c1 := cat{"Tom", 4}
//指针类型
c2 := &cat{"小花", 4}
//接收值类型
a1 = c1
fmt.Println(a1)
//接收指针类型
a1 = c2
fmt.Println(a1)
}指针接收者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20type car interface {
run()
}
type qqCar struct{
name string
}
func (q *qqCar)run(){
fmt.Println("奇瑞QQ")
}
func main() {
//定义接口变量
var ca car
//指针接收者只能接收指针类型
ca1 := &qqCar{"奇瑞QQ"}
ca = ca1
fmt.Println(ca)
}
类型与接口的关系
一个类型可以实现多个接口
1 | type eater interface { |
多个类型实现一个接口
1 | type dog struct{} |
一个接口的方法,不一定需要一个类型完全实现,接口的方法可以通过在类型中嵌入其他类型或者结构体来实现。
1 | type animal interface { |
接口嵌套
接口与接口之间可以进行嵌套创造出新接口
1 | //接口可以嵌套接口 |
空接口
空接口是指没有定义任何方法的接口。任何类型都实现了空接口。
空接口类型的变量可以储存任意类型的变量。
空接口用作方法的参数
1 | //空接口用作方法的参数 |
空接口作为map的值
1 | var maps map[string]interface{} |
类型断言
空接口可以储存任意类型的值,使用类型断言获取其具体的值
1 | //value:该接口类型的值,T 是否为T(string)类型 |
要断言多次可以使用switch进行断言
1 | func assign2(a interface{}){ |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 DurianLollipop的个人博客!
评论