内容简介:如interface(接口)是golang最重要的特性之一,Interface类型可以定义interface是为实现多态功能,多态是指代码可以根据类型的具体实现采取不同行为的能力。如果一个类型实现了某个接口,所有使用这个接口的地方,都可以支持这种类型的值。
如 Go method 中提及,Golang没有明确支持多态,但是通过其他手段可以实现类似C++中的多态特性,即本文中即将介绍的Go interface功能。
interface定义
interface(接口)是golang最重要的特性之一,Interface类型可以定义 一组方法 ,但是这些不需要实现。请注意:此处限定是 一组方法 ,既然是方法,就不能是变量;而且是 一组 ,表明可以有多个方法。再多声明一点,interface本质上是一种类型,确切的说,是 指针类型 ,此处暂且不多表,后文中自然能体会到。
interface是为实现多态功能,多态是指代码可以根据类型的具体实现采取不同行为的能力。如果一个类型实现了某个接口,所有使用这个接口的地方,都可以支持这种类型的值。
type 接口名称 interface { method1(参数列表) 返回值列表 method2(参数列表) 返回值列表 ... methodn(参数列表) 返回值列表 }
接口通常以er作为名称后缀,方法名是声明组成部分,但参数名可不同或省略。如果接口没有任何方法声明,那么就是一个空接口(interface{}),它的用途类似面向对象里的根类型Object,可被赋值为任何类型的对象。接口变量默认值是nil。如果实现接口的类型支持,可做相等运算。
func main() { var t1,t2 interface{} println(t1==nil,t1==t2) t1,t2=100,100 println(t1==t2) t1,t2=map[string]int{},map[string]int{} println(t1==t2) }
输出为
true true true panic:runtime error:comparing uncomparable type map[string]int
此外,还可以像匿名字段那样,嵌入其他接口。目标类型方法集中必须拥有包含嵌入接口方法在内的全部方法才算实现了该接口。
type stringer interface{ string()string } type tester interface{ stringer // 嵌入其他接口 test() } type data struct{} func(*data)test() { } func(data)string()string{ return"" } func main() { var d data var t tester= &d t.test() println(t.string()) }
interface应用场景
类型转换
类型推断可将接口变量还原为原始类型,或用来判断是否实现了某个更具体的接口类型。
type data int func(d data)String()string{ return fmt.Sprintf("data:%d",d) } func main() { var d data=15 var x interface{} =d if n,ok:=x.(fmt.Stringer);ok{ // 转换为更具体的接口类型 fmt.Println(n) } if d2,ok:=x.(data);ok{ // 转换回原始类型 fmt.Println(d2) } e:=x.(error) // 错误:main.data is not error fmt.Println(e) }
输出为:
data:15 data:15 panic:interface conversion:main.data is not error:missing method Error
但是此处会触发 panic
,使用ok-idiom模式,即便转换失败也不会引发panic。还可用switch语句在多种类型间做出推断匹配,这样空接口就有更多发挥空间。
func main() { var x interface{} =func(x int)string{ return fmt.Sprintf("d:%d",x) } switch v:=x.(type) { // 局部变量v是类型转换后的结果 case nil: println("nil") case*int: println(*v) case func(int)string: println(v(100)) case fmt.Stringer: fmt.Println(v) default: println("unknown") } }
输出为:
d:100
实现多态功能
多态功能是interface实现的重要功能,也是Golang中的一大行为特色,其多态功能一般要结合Go method实现,作为函数参数可以容易的实现多台功能。
package main import "fmt" // notifier是一个定义了通知类行为的接口 type notifier interface { notify() } // 定义user及user.notify方法 type user struct { name string email string } func (u *user) notify() { fmt.Printf("Sending user email to %s<%s>\n", u.name, u.email) } // 定义admin及admin.notify方法 type admin struct { name string email string } func (a *admin) notify() { fmt.Printf("Sending admin email to %s<%s>\n", a.name, a.email) } func main() { // 创建一个user值并传给sendNotification bill := user{"Bill", "bill@email.com"} sendNotification(&bill) // 创建一个admin值并传给sendNotification lisa := admin{"Lisa", "lisa@email.com"} sendNotification(&lisa) } // sendNotification接受一个实现了notifier接口的值 // 并发送通知 func sendNotification(n notifier) { n.notify() }
上述代码中实现了一个多态的例子,函数 sendNotification
接受一个实现了notifier接口的值作为参数。既然任意一个实体类型都能实现该接口,那么这个函数可以针对任意实体类型的值来执行 notify
方法,调用 notify
时,会根据对象的实际定义来实现不同的行为,从而实现多态行为。
以上所述就是小编给大家介绍的《Go interface详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- Flutter 完整开发实战详解(十六、详解自定义布局实战)
- 数据结构 1 线性表详解 链表、 栈 、 队列 结合JAVA 详解
- 详解Openstack环境准备
- Java泛型详解
- iOS RunLoop 详解
- Raft协议详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。