鸭子类型在软件开发中意味着什么?
当前回答
假设您正在设计一个简单的函数,该函数获取一个Bird类型的对象并调用它的walk()方法。你可以考虑两种方法:
这是我的函数,我必须确保它只接受Bird类型,否则代码将无法编译。如果有人想使用我的功能,他们必须知道我只接受鸟类。 我的函数获取任何对象,我只调用对象的walk()方法。因此,如果对象可以walk(),那么它是正确的。如果不能,我的函数就会失败。所以,这里的对象是鸟还是其他东西并不重要,重要的是它能走路()(这是鸭子类型)。
必须考虑到鸭子类型在某些情况下可能是有用的。例如,Python经常使用duck类型。
读有用的书
在Java、Python和JavaScript中都有很好的鸭子类型的例子 https://en.wikipedia.org/wiki/Duck_typing等。 这里也有一个很好的答案,它描述了动态的优点 动态类型及其缺点:动态类型所能带来的生产力提升是什么?
其他回答
我看到很多答案都在重复这句老话:
如果它长得像鸭子,叫声也像鸭子,那它就是鸭子
然后深入解释可以使用duck typing做什么,或者一个似乎进一步混淆了概念的示例。
我觉得没什么用。
这是我发现的关于鸭子打字的最好的简单英语回答:
Duck Typing意味着对象是根据它能做什么来定义的,而不是根据它能做什么来定义的 它是什么。
这意味着我们不太关心对象的类/类型,而更关心可以对其调用哪些方法以及可以对其执行哪些操作。我们不关心它的类型,我们只关心它能做什么。
Duck typing 意味着一个操作没有正式指定其操作数必须满足的要求,而只是使用给定的条件进行尝试。
与其他人所说的不同,这并不一定与动态语言或继承问题有关。
示例任务:在对象上调用某个方法Quack。
如果不使用duck-typing,执行此任务的函数f必须事先指定其参数必须支持某种方法Quack。常用的方法是使用接口
interface IQuack {
void Quack();
}
void f(IQuack x) {
x.Quack();
}
调用f(42)失败,但f(donald)工作,只要donald是一个iquack子类型的实例。
另一种方法是结构类型—但同样,方法Quack()是正式指定的,任何不能提前证明它是嘎嘎作响的东西都会导致编译器失败。
def f(x : { def Quack() : Unit }) = x.Quack()
我们甚至可以写成
f :: Quackable a => a -> IO ()
f = quack
在Haskell中,Quackable类型类确保了方法的存在。
So how does **duck typing** change this?
好吧,正如我所说的,duck输入系统不指定需求,而只是尝试任何可行的方法。
因此,像Python这样的动态类型系统总是使用duck类型:
def f(x):
x.Quack()
如果f得到一个支持Quack()的x,一切正常,否则,它将在运行时崩溃。
但是鸭子类型并不意味着动态类型——事实上,有一种非常流行但完全静态的鸭子类型方法,它也没有给出任何要求:
template <typename T>
void f(T x) { x.Quack(); }
该函数没有以任何方式告诉它想要某个可以Quack的x,所以它只是在编译时尝试,如果一切正常,就没问题。
用鸭子打字技术的树遍历
def traverse(t):
try:
t.label()
except AttributeError:
print(t, end=" ")
else:
# Now we know that t.node is defined
print('(', t.label(), end=" ")
for child in t:
traverse(child)
print(')', end=" ")
在编程中,类型可以分为名义类型和结构类型。名义类型考虑类型的整个结构。从谁那里继承的等等。它们显然比结构类型更复杂。例如,在c#和Java中使用名义类型。
结构类型根本不考虑这些问题。对于结构类型,只有单一类型的结构是重要的。这是什么样子。在一个类的例子中。它是否具有相同的参数和预期的类型。这叫做鸭子打字。Duck Typing起源于Duck Test。
Dugtest的意思是:如果某物看起来像鸭子。如果它像鸭子一样游泳。如果它像鸭子一样嘎嘎叫。然后它是一只鸭子。相反地:如果一个测试用例不应用,那么它就不是鸭子。(https://en.wikipedia.org/wiki/Duck_test)
我认为把动态类型、静态类型和鸭子类型混在一起很容易混淆。Duck typing是一个独立的概念,即使是像Go这样的静态类型语言,也可以有一个实现Duck typing的类型检查系统。如果类型系统检查(已声明的)对象的方法而不检查类型,则可以将其称为duck类型语言。