很多编程语言都提供了接口,Golang接口最大的特点是它可以不必显式定义,只要一个类型实现了某个接口定义的所有方法,那它就实现了这个接口。
C#语言实现接口的代码:
1
2
3
4
5
6
7
8
9
10
11
12
|
public interface IMyInterface
{
void MyInterfaceFunc();
}
public class MyClass : IMyInterface
{
void IMyInterface.MyInterfaceFunc()
{
//some code
}
}
|
Golang中实现接口的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
type IMyInterface interface {
MyInterfaceFunc()
}
type MyClass struct {
}
func (p MyClass) MyInterfaceFunc() {
//some code
}
func main() {
var mc MyClass
var imc IMyInterface = mc
imc.MyInterfaceFunc()
}
|
可以看到在C#中我们需要显示指定类MyClass
实现了接口IMyInterface
,而在Golang中我们只要为MyClass
绑定接口定义的方法,就相当于实现了这个接口。
接口的组合
有时候我们需要在接口中包含其他接口定义的方法,C#的做法是通过接口之间的继承:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public interface IMyInterface
{
void MyInterfaceFunc();
}
public interface IMyInterface2 : IMyInterface
{
void MyInterfaceFunc2();
}
public class MyClass : IMyInterface2
{
public void MyInterfaceFunc()
{
//some code
}
public void MyInterfaceFunc2()
{
//some code
}
}
|
Golang通过嵌套:
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
|
type IMyInterface interface {
MyInterfaceFunc()
}
type IMyInterface2 interface {
IMyInterface
MyInterfaceFunc2()
}
type MyClass struct {
}
func (p MyClass) MyInterfaceFunc() {
//some code
}
func (p MyClass) MyInterfaceFunc2() {
//some code
}
func main() {
var mc MyClass
var imc2 IMyInterface2 = mc
imc2.MyInterfaceFunc2()
}
|
接口与指针
注意在为类型定义方法的时候有两种情况:为类型本身定义和为类型对应的指针定义。尽管在调用上由于语法糖的作用它们区别不是很明显,但是对应接口来说,为类型*MyClass
定义的方法并不属于类型MyClass
。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
func (p *MyClass) MyInterfaceFunc() {
//some code
}
func (p MyClass) MyInterfaceFunc2() {
//some code
}
func main() {
var mc MyClass
//var imc2 IMyInterface2 = mc //compile error
var imc2 IMyInterface2 = &mc // ok
}
|
接口的比较
当两个接口均为nil或者当它们的动态类型可以比较并且动态值满足相等比较时,这两个接口相等。
需要注意对接口进行相等比较并不总是安全的,如果接口的动态类型不可进行比较,会引发panic。
空接口
interface{}
没有定义任何方法的接口,可以用来表示任何类型的值。
类型断言
两种情况
1
2
3
4
5
6
|
//如果i的动态值是Type类型,断言成功,返回i的动态值,否则引发panic
var v Type = i.(Type)
//如果i的动态值满足InterfaceType,断言成功,返回InterfaceType类型接口,否则引发panic
var v2 InterfaceType = i.(InterfaceType)
//如果i的动态值满足InterfaceType,断言成功,返回InterfaceType类型接口和true,否则返回nil, false
v3, ok := i.(InterfaceType)
|
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
|
type IMyInterface interface {
MyInterfaceFunc()
}
type IMyInterface2 interface {
IMyInterface
MyInterfaceFunc2()
}
type IMyInterface3 interface {
IMyInterface2
MyInterfaceFunc3()
}
type MyClass struct {
}
func (p MyClass) MyInterfaceFunc() {
//some code
}
func (p MyClass) MyInterfaceFunc2() {
//some code
}
func main() {
var mc MyClass
var ni interface{} = mc
var mci_1 IMyInterface = ni.(IMyInterface) //ok
mci_1.MyInterfaceFunc()
var mci_2 IMyInterface2 = ni.(IMyInterface2) //ok
mci_2.MyInterfaceFunc2()
//var mci_3 IMyInterface3 = ni.(IMyInterface3)//panic
//mci_3.MyInterfaceFunc3()
mci_3, ok := ni.(IMyInterface3) //nil, false
if ok {
mci_3.MyInterfaceFunc3()
}
}
|
BGM