我遇到了“鸭子打字”的两种不同的定义。毫无疑问,有些人会告诉你,其中一个是“正确的”,另一个是“不正确的”。我只是试图证明它们都被使用,而不是告诉你它们都是“正确的”,但是我个人认为更广泛的含义没有错。
1)仅运行时输入。类型是对象的属性,而不是变量,因此当您调用某个对象的方法或以其他方式使用它的类型属性时,运行时会发现该方法的存在或不存在[*]。所以如果它“看起来像一只鸭子,像一只鸭子一样嘎嘎叫”(即如果事实证明它具有一个quack()
函数),那么它就是一只鸭子(无论如何,你可以像它一样对待它)。通过这个定义,C++模板落在第一个障碍,他们使用静态类型。
2)更一般用于原则,如果它看起来像一个鸭子,叫起来像鸭子则鸭子,是指其中接口隐含由操作定义进行任何设置的名称通过接口的消费者,而不是由生产者明确公布的接口(不管实现接口)。通过这个定义,C++模板确实使用了一种鸭式键入,但是在编译时确定“看起来像鸭子”是基于静态类型而不是动态类型,而不是在运行时。 “在编译时检查,这个变量的静态类型嘎嘎?”,而不是“在运行时检查,这个对象可以嘎嘎吗?”。
这个争论在我看来似乎是在于Python是否“拥有”这个词,以至于只有类似Python的类型系统可以被称为鸭子输入,或者其他人是否可以自由地使用这个词来表示类似的概念在不同的背景下。无论您认为它应该是什么意思,使用“jokey”术语似乎都是不负责任的,并要求每个人都从中理解相同的正式定义。 SO不是一个合适的论坛,可以告诉你“应该”是什么意思,除非有你提到的权威来源,比如字典或任何正式定义的学术论文。我想它可以告诉你它实际上是什么意思。
“通用编程”可以使用鸭子打字或不使用,具体取决于具体细节。 C++泛型容器确实使用“类型2”的鸭式输入,因为对于C++中的一般类型,不能保证你可以复制它,比较它,得到一个散列值等等。Java通用容器不能,Object
有足够的方法已经使它可以哈希等
相反,我怀疑你做的任何事情使用鸭子打字,可以合理地称为“通用编程”。所以我想,按照你所要求的条件,在鸭子打字中(无论是定义),GP> DT是大量可以称为“通用”的东西的严格子集。
[*]在某些情况下,您的动态语言可能会有一些静态分析以某种方式证明情况,但语言要求能够将此检查推迟到运行时,以防静态分析无法确定说。
通用编程的优点是编译时检查;鸭子打字的优点是灵活性。正如@Peter Lawrey指出的那样,Java不支持鸭子打字。 –