鸭子打字和通用编程

时间:2012-09-17 10:02:39

标签: java c++ templates generics duck-typing

我搜索了一段时间,我找不到一个明确而一般的答案,只有一些矛盾和特别的意见。 [1]

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

我知道泛型编程将在编译时处理,而鸭子类型将在运行时处理,但是我不知道如何定位它们。

最后,我不想开始辩论,所以我更希望得到理由,原因等等。

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

4 个答案:

答案 0 :(得分:7)

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

1)仅限运行时输入。类型是对象的属性,而不是变量,因此当您在对象上调用方法时,必然,或者根据其类型使用它具有的属性,是否存在方法在运行时[*]发现。因此,如果它“看起来像一只鸭子并且像鸭子一样嘎嘎叫”(即如果它有一个quack()功能)那么它“是”一只鸭子(无论如何,你可以像对待它一样)。通过这个定义当然C ++模板处于第一个障碍,他们使用静态类型。

2)一个名称更常用于原则,如果它看起来像一只鸭子并且像鸭子一样呱呱叫那么它就是一只鸭子,意味着任何接口隐式的设置由接口的使用者执行的操作定义,而不是由生产者明确通告的接口(无论实现接口)。通过这个定义,C ++模板确实使用了一种鸭子类型,但是在“编译时”,而不是在运行时,根据其静态类型而不是动态类型确定“看起来像鸭子”的东西。 “在编译时检查,这个变量的静态类型可以嘎嘎吗?”,而不是“在运行时检查,这个对象可以嘎嘎叫吗?”。

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

“通用编程”可以使用或不使用鸭子打字,具体取决于具体细节。 C ++通用容器确实使用“类型2”鸭子类型,因为对于C ++中的一般类型,不能保证您可以复制它,比较它,获取哈希值等等.Java通用容器不会,{{1}已经有足够的方法使它可以使用。

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

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

答案 1 :(得分:6)

这实际上是一个词汇问题。在最普遍的意义上, 泛型编程与编译时问题无关 运行时:它是一个普遍问题的解决方案。一个很好的例子 通用编程是运行时的Python,但它也是可能的 用C ++实现运行时泛型编程(成本很高) 在执行时间)。

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

答案 2 :(得分:2)

Java不支持使用该语言进行鸭子输入。它确实支持可以实现相同目标的反射。据我所知,它与Java的Generics没有任何关系,实际上让它们一起工作真的很痛苦。

答案 3 :(得分:1)

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

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

最后一句是问题的答案。