19.4 接口与动态类型

在经典的面向对象语言(像 C++,Java 和 C#)中,往往将数据和方法被封装为类的概念:类中包含它们两者,并且不能剥离。

Go 语言中没有类,数据(结构体或更一般的类型)和方法是一种松耦合的正交关系。Go 语言中的接口必须提供一个指定方法集的实现,但是更加灵活通用:任何提供了接口方法实现代码的类型都隐式地实现了该接口,而不用显式地声明。该特性允许我们在不改变已有的代码的情况下定义和使用新接口。

接收一个(或多个)接口类型作为参数的函数,其实参可以是任何实现了该接口的类型。 实现了某个接口的类型可以被传给任何以此接口为参数的函数 。

Go 语言动态类型的实现通常需要编译器静态检查的支持:当变量被赋值给一个接口类型的变量时,编译器会检查其是否实现了该接口的所有方法。我们也可以通过类型断言来检查接口变量是否实现了相应类型。

因此 Go 语言提供了动态语言的优点,却没有其他动态语言在运行时可能发生错误的缺点。Go 语言的接口提高了代码的分离度,改善了代码的复用性,使得代码开发过程中的设计模式更容易实现。