鸭子类型是动态语言的一种风格,这种风格下对象没有有效的语义,是由当前的属性和集合决定。这个概念源自鸭子测试。
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。
简单的说鸭子类型关注的不是对象本身,而是方法集的使用(个人感觉和弱类型的用意很像)。
假设你要你要统计一艘货船上有很多货单,每个货单有很多包裹及这些包裹的重量,现在你需要统计这艘船所有货单的包裹总数与总重量,那么怎么做?
# Fields:
# * package_count: number of packages in manifest (integer)
# * mass: total mass of all packages, in kilograms (BigDecimal)
class ShippingManifest
attr_accessor :package_count, :mass
end
def summarise_manifests
# Grab the latest set of Manifests (returns an Array)
manifest_set = ShippingManifest.all
# Initialize our counters
total_package_count = 0
total_mass = BigDecimal("0")
manifest_set.each do |m|
total_package_count += m.package_count
total_mass += m.mass
end
return [total_package_count, total_mass]
end
def summarise_manifests
ShippingManifest.all.sum
end
class ShippingManifest < ActiveResource::Base
# Returns a new instance of ShippingManifest containing the
# sum of both `mass` and `package_count`
def +(other)
self.dup.tap do |neu|
neu.mass = @mass + other.mass
neu.package_count = @package_count + other.package_count
end
end
end
Making Ruby Quack—Why We Love Duck Typing http://www.sitepoint.com/making-ruby-quack-why-we-love-duck-typing/