2012-09-17 40 views
4

我搜索了一段时间,我找不到一个确定的和一般的答案,只有一些矛盾和特殊的意见。 [1]鸭子打字和通用编程

所以我想知道鸭子打字和泛型编程之间有什么关系? (DT < GP,DT == GP,DT> GP)。通过泛型编程,我特别提到了C++模板或Java泛型,但是如果可能的话,与概念相关的一般答案会受到欢迎。

我知道泛型编程将在编译时处理,而duck输入将在运行时处理,但我不知道如何定位它们。

最后,我不想开始辩论,所以我宁愿选择理由反对的理由。

[1] What's the relationship between C++ template and duck typing?

+0

通用编程的优点是编译时检查;鸭子打字的优点是灵活性。正如@Peter Lawrey指出的那样,Java不支持鸭子打字。 –

回答

6

我遇到了“鸭子打字”的两种不同的定义。毫无疑问,有些人会告诉你,其中一个是“正确的”,另一个是“不正确的”。我只是试图证明它们都被使用,而不是告诉你它们都是“正确的”,但是我个人认为更广泛的含义没有错。

1)仅运行时输入。类型是对象的属性,而不是变量,因此当您调用某个对象的方法或以其他方式使用它的类型属性时,运行时会发现该方法的存在或不存在[*]。所以如果它“看起来像一只鸭子,像一只鸭子一样嘎嘎叫”(即如果事实证明它具有一个quack()函数),那么它就是一只鸭子(无论如何,你可以像它一样对待它)。通过这个定义,C++模板落在第一个障碍,他们使用静态类型。

2)更一般用于原则,如果它看起来像一个鸭子,叫起来像鸭子则鸭子,是指其中接口隐含由操作定义进行任何设置的名称通过接口的消费者,而不是由生产者明确公布的接口(不管实现接口)。通过这个定义,C++模板确实使用了一种鸭式键入,但是在编译时确定“看起来像鸭子”是基于静态类型而不是动态类型,而不是在运行时。 “在编译时检查,这个变量的静态类型嘎嘎?”,而不是“在运行时检查,这个对象可以嘎嘎吗?”。

这个争论在我看来似乎是在于Python是否“拥有”这个词,以至于只有类似Python的类型系统可以被称为鸭子输入,或者其他人是否可以自由地使用这个词来表示类似的概念在不同的背景下。无论您认为它应该是什么意思,使用“jokey”术语似乎都是不负责任的,并要求每个人都从中理解相同的正式定义。 SO不是一个合适的论坛,可以告诉你“应该”是什么意思,除非有你提到的权威来源,比如字典或任何正式定义的学术论文。我想它可以告诉你它实际上是什么意思。

“通用编程”可以使用鸭子打字或不使用,具体取决于具体细节。 C++泛型容器确实使用“类型2”的鸭式输入,因为对于C++中的一般类型,不能保证你可以复制它,比较它,得到一个散列值等等。Java通用容器不能,Object有足够的方法已经使它可以哈希等

相反,我怀疑你做的任何事情使用鸭子打字,可以合理地称为“通用编程”。所以我想,按照你所要求的条件,在鸭子打字中(无论是定义),GP> DT是大量可以称为“通用”的东西的严格子集。

[*]在某些情况下,您的动态语言可能会有一些静态分析以某种方式证明情况,但语言要求能够将此检查推迟到运行时,以防静态分析无法确定说。

2

Java不支持的语言鸭打字。它确实支持可以实现相同目的的反射。就我所见,它与Java的泛型没有任何关系,实际上让它们一起工作真是一个痛苦。

+0

这是问题的答案吗? – jogojapan

+2

它适用于Java的问题的答案。我无法给出一个很好的答案,说明它在C++中的工作原理。 –

6

这实在是一个词汇的问题。从一般意义上讲, 通用编程与编译时与运行时的问题无关:它是一个常见问题的解决方案。 是一个很好的例子,其中泛型编程运行时是Python,但也可能使用 来实现C++中的运行时通用编程(执行时间为 )。

鸭子打字是一个正交的概念,通常用于暗示 运行时键入。同样,最常被引用的现代示例是Python,但是从Lisp开始的许多语言在过去使用它。作为一般规则,C++和Java都明确地提出了 选项而不是来支持鸭子打字。这是一种权衡:安全性与灵活性(或编译时错误与运行时错误)的关系。

1

对我而言,“鸭子打字”意味着没有明确的一致性关系。如果某件东西像鸭子一样走路,像鸭子一样说话,它可以像鸭子一样对待,并且不需要明确声明它是鸭子。在C++中,它不需要从Duck基类继承:inheritance是一种声明一个类明确地符合另一个类的接口的方式。

这个概念与是否在运行时或编译时发生类型检查是正交的。像Smalltalk这样的语言提供了在运行时发生的鸭式输入(并且继承用于重用实现,而不是声明接口的一致性)。 C++模板是在编译时发生的鸭式输入的一种形式。

而最后一句是对这个问题的回答。