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


当前回答

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

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

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

维基百科有更多的信息。

其他回答

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

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

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


读有用的书

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

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

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

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

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).

我知道我没有给出一个笼统的答案。在Ruby中,我们不声明变量或方法的类型——所有东西都是某种类型的对象。 规则是"类不是类型"

在Ruby中,类从来都不是(好吧,几乎从来都不是)类型。相反,对象的类型更多地由该对象可以做什么来定义。在Ruby中,我们称之为duck typing。如果一个对象像鸭子一样走路,像鸭子一样说话,那么解释器很乐意把它当作鸭子来对待。

例如,您可能正在编写一个例程,将歌曲信息添加到字符串中。如果你有c#或Java背景,你可能会这样写:

def append_song(result, song)
    # test we're given the right parameters 
    unless result.kind_of?(String)
        fail TypeError.new("String expected") end
    unless song.kind_of?(Song)
        fail TypeError.new("Song expected")
end

result << song.title << " (" << song.artist << ")" end
result = ""

append_song(result, song) # => "I Got Rhythm (Gene Kelly)"

采用Ruby的鸭子输入,您可以编写一些简单得多的东西:

def append_song(result, song)
    result << song.title << " (" << song.artist << ")"
end

result = ""
append_song(result, song) # => "I Got Rhythm (Gene Kelly)"

你不需要检查参数的类型。如果它们支持<<(在结果的情况下)或标题和艺术家(在歌曲的情况下),一切都会正常工作。如果没有,你的方法无论如何都会抛出一个异常(就像你检查了类型一样)。但如果没有检查,你的方法突然变得灵活多了。你可以向它传递一个数组、一个字符串、一个文件或任何其他使用<<追加的对象,它就可以工作了。

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()

这就是所有的,我们中的许多人已经直观地知道鸭子打字。

在编程中,类型可以分为名义类型和结构类型。名义类型考虑类型的整个结构。从谁那里继承的等等。它们显然比结构类型更复杂。例如,在c#和Java中使用名义类型。

结构类型根本不考虑这些问题。对于结构类型,只有单一类型的结构是重要的。这是什么样子。在一个类的例子中。它是否具有相同的参数和预期的类型。这叫做鸭子打字。Duck Typing起源于Duck Test。

Dugtest的意思是:如果某物看起来像鸭子。如果它像鸭子一样游泳。如果它像鸭子一样嘎嘎叫。然后它是一只鸭子。相反地:如果一个测试用例不应用,那么它就不是鸭子。(https://en.wikipedia.org/wiki/Duck_test)