鸭子类型在软件开发中意味着什么?


当前回答

假设您正在设计一个简单的函数,该函数获取一个Bird类型的对象并调用它的walk()方法。你可以考虑两种方法:

这是我的函数,我必须确保它只接受Bird类型,否则代码将无法编译。如果有人想使用我的功能,他们必须知道我只接受鸟类。 我的函数获取任何对象,我只调用对象的walk()方法。因此,如果对象可以walk(),那么它是正确的。如果不能,我的函数就会失败。所以,这里的对象是鸟还是其他东西并不重要,重要的是它能走路()(这是鸭子类型)。

必须考虑到鸭子类型在某些情况下可能是有用的。例如,Python经常使用duck类型。


读有用的书

在Java、Python和JavaScript中都有很好的鸭子类型的例子 https://en.wikipedia.org/wiki/Duck_typing等。 这里也有一个很好的答案,它描述了动态的优点 动态类型及其缺点:动态类型所能带来的生产力提升是什么?

其他回答

我认为把动态类型、静态类型和鸭子类型混在一起很容易混淆。Duck typing是一个独立的概念,即使是像Go这样的静态类型语言,也可以有一个实现Duck typing的类型检查系统。如果类型系统检查(已声明的)对象的方法而不检查类型,则可以将其称为duck类型语言。

Duck typing:

如果它像鸭子一样说话和走路,那么它就是一只鸭子

这通常被称为诱拐(诱拐推理或也称为归纳,我认为一个更清晰的定义):

从C(结论,我们所看到的)和R(规则,我们所知道的),我们接受/决定/假设P(前提,属性),换句话说,一个给定的事实 ... 医学诊断的基础 和鸭子:C =走路,说话,R =像鸭子,P =它是一只鸭子

回到编程:

对象o有方法/属性mp1和接口/类型T 要求/定义mp1 对象o有方法/属性mp2,接口/类型T要求/定义mp2 ...

因此,不仅仅是简单地接受mp1…在任何对象上,只要它满足mp1的某些定义…,编译器/运行时也应该接受断言o是类型T

上面的例子是这样的吗?Duck输入实质上就是没有输入吗?或者我们应该称之为隐式类型?

简单的解释

鸭子打字是什么?

“如果它走路像鸭子,嘎嘎叫像....等等”——是的,但这是什么意思??!

我们感兴趣的是“对象”能做什么,而不是它们是什么。

让我们用一个例子来分解它:

详情见下文:

Duck Typing功能示例:

想象我有一根魔杖。它有特殊的力量。如果我挥舞魔杖,对一辆车说“开车!”,那么,它就会开车!

它对其他东西有用吗?不确定,所以我在卡车上试了试。哇,它也能开车!然后我在飞机上、火车上和1 Woods(这是一种人们用来“驾驶”高尔夫球的高尔夫球杆)上尝试了一下。他们都开车!

但它能用在茶杯上吗?错误:KAAAA-BOOOOOOM !结果不太好。====>茶杯不能开车!!咄! ?

这就是duck typing的基本概念。这是一个先试后买的系统。如果有效,一切都好。但如果失败了,就像手榴弹还在你手上一样,它会在你脸上爆炸。

换句话说,我们感兴趣的是对象能做什么,而不是对象是什么。

那么像c#或Java等语言呢?

如果我们关心的对象实际上是什么,那么我们的魔术只会对预先设置的,授权的类型起作用——在这种情况下是汽车,但对其他可以驾驶的对象无效:卡车,轻便摩托车,突突车等。它不能在卡车上工作,因为我们的魔杖期望它只能在汽车上工作。

换句话说,在这种情况下,魔杖非常仔细地观察物体是什么(它是一辆汽车吗?),而不是物体能做什么(例如汽车、卡车等能不能开车)。

让卡车驾驶的唯一方法是,如果您能够以某种方式让魔杖同时期待卡车和汽车(也许通过“实现一个公共接口”)。这可以通过一种叫做“多态”的技术来实现,也可以通过使用“接口”来实现——它们是一样的东西。如果你喜欢漫画,想要一个解释,看看我关于界面的漫画。

总结:关键外卖

在duck类型中,重要的是对象实际上可以做什么,而不是对象是什么。

序言

我试图通过去除迂腐的细微差别和学术语言来保持它的简单/有趣。这种方法并不适合所有人——如果你更喜欢学术定义,可以看看维基百科上关于“回避输入”的文章,或者《心灵捕手》中马特·达蒙对“回避输入”的解释;)

代码示例

但是高尔夫球杆怎么能像汽车一样“驾驶”呢?他们不一样吗?但如果你使用的是Ruby这样的语言:

class Car
   def drive
      "I"m driving a Car!"
   end
end

class GolfClub
   def drive
      "I"m driving a golf club!"
   end 
end

def test_drive(item)   
   item.drive # don't care what it is, all i care is that it can "drive"
end

car = Car.new
test_drive(car) #=> "I'm driving a Car"

club = GolfClub.new
test_drive(club) #=> "I"m driving a GolfClub"

“鸭子打字”这个词是一个谎言。

“走路像鸭子,叫起来像鸭子,那就是鸭子”这句俗语在这里一次又一次地被重复着。

但这并不是鸭子打字(或者我们通常所说的鸭子打字)的意思。所有我们正在讨论的鸭子打字,是试图强制命令的东西。看看有什么东西是不是嘎嘎叫,不管它说什么。但是并没有推论出这个物体是不是鸭子。

For true duck typing, see type classes. Now that follows the idiom “If it walks like a duck and quacks like a duck then it is a duck.". With type classes, if a type implements all the methods that are defined by a type class, it can be considered a member of that type class (without having to inherit the type class). So, if there is a type class Duck which defines certain methods (quack and walk-like-duck), anything that implements those same methods can be considered a Duck (without needing to inherit Duck).

它是一个用于没有强类型的动态语言中的术语。

其思想是,为了调用对象上的现有方法,您不需要指定类型——如果在对象上定义了方法,则可以调用它。

这个名字来源于一句话“如果它看起来像鸭子,叫起来像鸭子,那它就是鸭子”。

维基百科有更多的信息。