接口(interface)是对其他类型行为的抽象。接口是一种约束形式,其中只包括成员函数定义,不包含成员函数实现,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口。
接口的定义:
type 接口名称 interface { method_name1(参数列表) [return_type] method_name2(参数列表) [return_type] method_name3(参数列表) [return_type] ... } 复制代码
接口赋值
Go 语言接口不支持直接实例化,支持赋值操作,从而快速实现接口与实现类的映射。接口赋值有:
- 将实现接口的对象实例赋值给接口
- 一个接口赋值给另一个接口
- 将实现接口的对象实例赋值给接口
// 定义一个接口 NumberI type NumberI interface{ Equal(i Number) bool } type Number int //判断是否相等 func (x Number) Equal(i Number) bool{ return x == 1 } 复制代码
上面示例,Number 类型实现了 NumberI 接口中的所有方法,即实现了 NumberI 接口。然后便可以将 Number 类型对应的对象实例赋值给 NumberI 接口。
var x Number = 8 var y NumberI = &x 复制代码
可以将实例 x 的指针赋值给了接口变量,因为Go语言会自动生成一个新的与之对应的指针成员方法,即:
func (x Number) Equal(i Number) bool func (x* Number) Equal(i Number) bool{ return (*x).Equal(i) } 复制代码
- 接口赋值给接口
Go语言中,只要两个接口有相同的方法列表(顺序无关),那么他们就是等同的,可以相互赋值。 如下 package1、package2 两个包中的两个接口并区别。
- 任何实现了 package1.NumberInterface1 接口的类,也实现了 package2.NumberInterface2
- 任何实现了 package1.NumberInterface1 接口的对象实例都可以赋值给 package2.NumberInterface2
package1 type NumberInterface1 interface { Equal(i int)bool } 复制代码
package2 type NumberInterface2 interface { Equal(i int)bool } 复制代码
// 实现两个接口的类 Number type Number int func (x Number) Equal(i int)bool{ return int(x) == i } 复制代码
下面的复制代码都是合法的:
var a number = 6 var b package1.NumberInterface1 = a var c package2.NumberInterface2 = b 复制代码
另外,接口赋值并不要求两个接口方法完全相同,若接口 A 的方法列表为接口B 的子集,那么 B 可以复制给 A。例如:
package1 type A interface { Equal(i int)bool } 复制代码
package2 type B interface { Equal(i int)bool Sum(i int) } // 实现两个接口的类 Number type Number int func (x Number) Equal(i int)bool{ return int(x) == i } func (n *Number) Sum(i int){ *n = *n + Number(i) } 复制代码
下面的复制代码都是合法的:
var a number = 6 var b package2.NumberInterface2 = a var c package1.NumberInterface1 = b 复制代码
类型推断
类型推断可以将接口变量还原为原始类型,还可用 switch...case 语句进行多种类型推断匹配。
var a interface{} = func(a int)string{ return fmt.Sprintf("d:%d",a) } switch b := a.(type) { case nil: fmt.Println("nil") case *int: fmt.Println(*b) case func(int) string: fmt.Println(b(11)) default: fmt.Println("unknow") } //d:11