鸭子类型在软件开发中意味着什么?
当前回答
我认为把动态类型、静态类型和鸭子类型混在一起很容易混淆。Duck typing是一个独立的概念,即使是像Go这样的静态类型语言,也可以有一个实现Duck typing的类型检查系统。如果类型系统检查(已声明的)对象的方法而不检查类型,则可以将其称为duck类型语言。
其他回答
看看语言本身可能会有所帮助;它经常帮助我(我的母语不是英语)。
在鸭子打字中:
1)打字这个词并不是指在键盘上打字(就像我脑海中一直存在的形象那样),而是指确定“那是什么类型的东西?”
2) duck这个词表示决定是如何完成的;这是一种“松散的”定语,比如:“如果它像鸭子一样走路……那它就是一只鸭子。”之所以说“松散”,是因为这个东西可能是一只鸭子,也可能不是,但它是否真的是一只鸭子并不重要;重要的是我能像对待鸭子一样对待它,期待鸭子表现出的行为。我可以喂它面包屑,它可能会向我扑来,向我冲来,或者后退……但它不会像灰熊那样把我吃掉。
假设您正在设计一个简单的函数,该函数获取一个Bird类型的对象并调用它的walk()方法。你可以考虑两种方法:
这是我的函数,我必须确保它只接受Bird类型,否则代码将无法编译。如果有人想使用我的功能,他们必须知道我只接受鸟类。 我的函数获取任何对象,我只调用对象的walk()方法。因此,如果对象可以walk(),那么它是正确的。如果不能,我的函数就会失败。所以,这里的对象是鸟还是其他东西并不重要,重要的是它能走路()(这是鸭子类型)。
必须考虑到鸭子类型在某些情况下可能是有用的。例如,Python经常使用duck类型。
读有用的书
在Java、Python和JavaScript中都有很好的鸭子类型的例子 https://en.wikipedia.org/wiki/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,所以它只是在编译时尝试,如果一切正常,就没问题。
Duck Typing:
let anAnimal
if (some condition)
anAnimal = getHorse()
else
anAnimal = getDog()
anAnimal.walk()
上述函数调用在结构类型中无效
以下将适用于结构类型:
IAnimal anAnimal
if (some condition)
anAnimal = getHorse()
else
anAnimal = getDog()
anAnimal.walk()
这就是所有的,我们中的许多人已经直观地知道鸭子打字。
马特·达蒙解释了《心灵捕手》中的鸭子打字
笔录如下:这里有视频链接。
好吧,我们会有问题吗?
克拉克:没问题。我只是希望你能告诉我鸭子打字到底是什么?我的观点是,鸭系没有很好的定义,也不强
WILL: [interrupting] …and neither is strong typing. Of course that's your contention. You're a first year grad student: you just got finished reading some article on duck typing, probably on StackOverflow, and you’re gonna be convinced of that until next month when you get to the Gang of Four, and then you’re gonna be talking about how Google Go and Ocaml are statistically typed languages with structural sub-tying construction. That's going to last until next year, till you're probably gonna be in here regurgitating Matz, talkin’ about, you know, the Pre-Ruby 3.0 utopia and the memory allocating effects of sub-typing on the GC.
克拉克:(吓了一跳)事实上我不会,因为马茨大大低估了——的影响
WILL:“Matz极大地低估了Ruby 3.0的GC对性能的影响。你是从Donald Knuth的《计算机编程艺术》第98页学到的,对吧?是的,我也读过。你打算为我们剽窃整篇文章吗——你对这件事有什么想法吗?或者,这是你的做法吗,你进入堆栈溢出,你读了r/ruby上一些晦涩的段落,然后你假装,你把它当作你自己的——你自己的想法,只是为了取悦一些女孩,让我的朋友难堪?
[克拉克惊呆了]
威尔:像你这样的人最可悲的是,50年后你会开始自己思考,你会发现生活中有三件事是肯定的。第一,不要那样做。第二,如果它走路像鸭子,那它就是鸭子。第三,你花了十五万美元接受本·科西本可以零美分就能得到的教育。
克拉克:是的,但我会有学位,而你会在我们去滑雪的路上,在汽车餐厅给我的孩子们提供一些廉价的html。
威尔:(微笑)也许吧。但至少我不会没有创意。
(打)
威尔:你遇到了(代码的出现)问题?我想我们可以出去谈谈。
克拉克:没问题
一段时间后:
威尔:你喜欢苹果吗?
克拉克说,嗯?
威尔:你觉得这些苹果怎么样?(砰:威尔把一封信重重地贴在窗户上。)我要谷歌的报价!(出示克拉克的录取通知书,上面有他的面试答案:一张鸭子走路、说话、表现得像一只……鹅)。
不必再说
最后。
(这是对旧答案的一个脚注:)