一、interface简介
interface(接口)是golang最重要的特性之一,Interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量。
简单的说:
- interface是方法的集合
- interface是一种类型,并且是指针类型
- interface的更重要的作用在于多态实现
interface定义
type 接口名称 interface { method1 (参数列表) 返回值列表 method2 (参数列表) 返回值列表 ... }
interface使用
- 接口的使用不仅仅针对结构体,自定义类型、变量等等都可以实现接口。
- 如果一个接口没有任何方法,我们称为空接口,由于空接口没有方法,所以任何类型都实现了空接口。
- 要实现一个接口,必须实现该接口里面的所有方法。
package main import "fmt" //定义接口 type Skills interface { Running() Getname() string } type Student struct { Name string Age int } // 实现接口 func (p Student) Getname() string{ //实现Getname方法 fmt.Println(p.Name ) return p.Name } func (p Student) Running() { // 实现 Running方法 fmt.Printf("%s running",p.Name) } func main() { var skill Skills var stu1 Student stu1.Name = "wd" stu1.Age = 22 skill = stu1 skill.Running() //调用接口 } //wd running
多态
上面提到了,go语言中interface是实现多态的一种形式,所谓多态,就是一种事物的多种形态,与python中类的多态是一致的。
同一个interface,不同的类型实现,都可以进行调用,它们都按照统一接口进行操作。
在上面的示例中,我们增加一个Teacher结构体,同样实现接口进行说明:
package main import "fmt" type Skills interface { Running() Getname() string } type Student struct { Name string Age int } type Teacher struct { Name string Salary int } func (p Student) Getname() string{ //实现Getname方法 fmt.Println(p.Name ) return p.Name } func (p Student) Running() { // 实现 Running方法 fmt.Printf("%s running",p.Name) } func (p Teacher) Getname() string{ //实现Getname方法 fmt.Println(p.Name ) return p.Name } func (p Teacher) Running() { // 实现 Running方法 fmt.Printf("\n%s running",p.Name) } func main() { var skill Skills var stu1 Student var t1 Teacher t1.Name = "wang" stu1.Name = "wd" stu1.Age = 22 skill = stu1 skill.Running() skill = t1 t1.Running() } //wd running //wang running
接口嵌套
go语言中的接口可以嵌套,可以理解我继承,子接口拥有父接口的所有方法,并且想要使用该子接口的话,必须将父接口和子接口的所有方法都实现。
type Skills interface { Running() Getname() string } type Test interface { sleeping() Skills //继承Skills }
类型转换
由于接口是一般类型,当我们使用接口时候可能不知道它是那个类型实现的,基本数据类型我们有对应的方法进行类型转换,当然接口类型也有类型转换。
当然我们也可以用这个方式来进行类型的判断。
转换方式:
var s int var x interface x = s y , ok := x.(int) //将interface 转为int,ok可省略 但是省略以后转换失败会报错,true转换成功,false转换失败, 并采用默认值
示例:
package main import "fmt" func main() { var x interface{} s := "WD" x = s y,ok := x.(int) z,ok1 := x.(string) fmt.Println(y,ok) fmt.Println(z,ok1) } //0 false //WD true
判断类型示例:
package main import "fmt" type Student struct { Name string } func TestType(items ...interface{}) { for k, v := range items { switch v.(type) { case string: fmt.Printf("type is string, %d[%v]\n", k, v) case bool: fmt.Printf("type is bool, %d[%v]\n", k, v) case int: fmt.Printf("type is int, %d[%v]\n", k, v) case float32, float64: fmt.Printf("type is float, %d[%v]\n", k, v) case Student: fmt.Printf("type is Student, %d[%v]\n", k, v) case *Student: fmt.Printf("type is Student, %d[%p]\n", k, v) } } } func main() { var stu Student TestType("WD", 100, stu,3.3) } //type is string, 0[WD] //type is int, 1[100] //type is Stud