鸭子类型 vs 构造化类型 vs 标称类型(请简述鸭子类型的含义)

admin|
177


Go 语言是哪一种?

编程语言具有类型概念 - 布尔类型,字符串,整型或者被称为类或者构造体的愈加复杂的构造。按照若何将类型解析并赋值给各类构造(例如变量,表达式,函数,函数参数等),编程语言能够归类为鸭子类型,构造化类型或标称类型。

素质上,分类决定了对象若何被解析并揣度为详细的类型。

鸭子类型语言利用鸭子测试来评估对象能否能够被解析为特定的类型。鸭子测试暗示:

若是它看起来像鸭子,像鸭子一样泅水,像鸭子一样嘎嘎叫,那它很可能就是鸭子。

*我将利用 Go 语言语法来解释那些设法 - 将那些示例做为伪代码阅读 - 它与 Go 语言规则无关

以下代码片段是鸭子类型语言的示例。因为 Mallard 能够嘎嘎叫,所以它是一只鸭子。

type Mallard struct {        }        func (m Mallard) quack() {        }        func makeDuckQuack(duck Duck) {        duck.quack()        }        func main() {        makeDuckQuack(Mallard{})        }

在上面的示例中,Duck 能够是肆意类型,它能够是接口或者另一个类型,但是关于 makeDuckQuack 函数而言,独一的要求就是传递一个能够施行 quack 函数的对象做为参数。

鸭子类型语言凡是没有编译期查抄。类型的解析息争释发作在运行时 - 那可能招致运行时错误。

例如,以下代码片段能够一般编译,但是因为 Dog 类型不撑持 quack() 函数,会产生运行时错误。

type Dog struct {        }        func (d Dog) bark() {        }        func makeDuckQuack(duck Duck) {        duck.quack()        }        func main() {        makeDuckQuack(Dog{})        }

Python 和 Javascript 是流行的鸭子类型语言。

在另一端,标称类型语言期望法式员明白地对类型停止挪用以供编译器解释。

type Duck interface {        quack()        }        type Mallard struct { //Mallard doesnt implement Duck interface        }        func (m Mallard) quack() {        }        func makeDuckQuack(duck Duck) {        duck.quack()        }        func main() {        makeDuckQuack(Mallard{}) //This will not work as Mallard doesnt explicitly implement Duck.        }

在上面的示例中,法式员需要明白地实现 Duck 接口。能够说,显示关系意味着更强的可读性。

明白定义 Marllard 和 Duck 之间的关系也意味着包罗 Marllard 构造的包依赖于包罗 Duck 构造的包。那可能永久也不是一件功德,而且增加了整个应用法式的复杂性。

标称类型语言次要包罗 Java,C++。

构造化类型语言介于两者之间,应用法式员无需明白定义用于解释的类型,但是编译器会停止编译期检测来确保法式的完好性。

type Duck interface {        quack()        }        type Mallard struct { //Mallard doesnt implement Duck interface        }        func (m Mallard) quack() {        }        type Dog struct {        }        func (d Dog) bark() {        }        func makeDuckQuack(duck Duck) {        duck.quack()        }        func main() {        makeDuckQuack(Mallard{}) // Okay        makeDuckQuack(Dog{}) // Not Okay        }

在上面的示例中,法式员无需指定 Mallard 是 Duck 类型。语言编译器将 Mallard 解释为 Duck - 因为它具有 quack 函数。但是 Dog 不是一个 Duck,因为 Dog 不具有 quack 函数。

Go 是构造化类型语言。

结论

鸭子类型语言为法式员供给了更大的灵敏性。法式员只需写起码量的代码。但是那些语言可能其实不平安,会产生运行时错误。

标称类型语言要求法式员显示挪用类型,那意味着更多的代码和更少的灵敏性(附加的依赖)。

构造化类型语言供给了一种平衡,它需要编译期查抄,但不需要显示声明依赖。

在利用 Go(构造化类型)编程之前,我次要利用 Java(标称类型)。我喜好构造化类型语言供给的灵敏性,而又不会影响编译期类型平安。

via: 鸭子类型 vs 构造化类型 vs 标称类型

做者:Saurabh Nayar 译者:DoubleLuck 校对:polaris1119

本文由 GCTT 原创编译,Go语言中文网 荣誉推出