cdi*_*ins 24 type-systems duck-typing language-design definitions structural-typing
维基百科曾经说*关于鸭子打字:
在使用面向对象编程语言的计算机编程中,duck typing是一种动态类型,其中对象的当前方法和属性集确定有效语义,而不是从特定类或特定接口的实现继承.
(*Ed.注意:自从发布此问题以来,维基百科文章已经过编辑,删除了"动态"一词.)
它说关于结构类型:
结构类型系统(或基于属性的类型系统)是类型系统的主要类,其中类型兼容性和等价性由类型的结构决定,而不是通过显式声明.
它将结构子类型与鸭子类型进行对比,如下所示:
[结构系统]与... duck typing相反,其中仅检查在运行时访问的结构的一部分的兼容性.
然而,术语鸭子打字在我看来至少是直观地包含结构子打字系统.实际上维基百科说:
这个概念的名称[鸭子打字]是指鸭子测试,归功于James Whitcomb Riley,其措辞可能如下:"当我看到一只鸟像鸭子一样散步,像鸭子一样游动,像鸭子一样呱呱叫,我称这只鸟为鸭子."
所以我的问题是:为什么我不能将结构子类型称为鸭子打字?是否存在动态类型语言,这些语言也不能被归类为鸭子类型?
后记:
正如有人叫daydreamdrunk上reddit.com如此雄辩地提出,它 "如果它编译像鸭子,像鸭子链接..."
后后记
许多答案似乎基本上只是重复我已经在这里引用的内容,而没有解决更深层次的问题,这就是为什么不使用术语duck-typing来涵盖动态类型和结构子类型?如果您只想谈论鸭子类型而不是结构子类型,那么只需调用它:动态成员查找.我的问题是没有关于鸭子打字这个术语对我说,这只适用于动态语言.
dsi*_*cha 26
C++和D模板是鸭子打字的一个完美的例子,它不是动态的.绝对是:
键入一个对象的当前方法和属性集确定有效语义,而不是从特定类或特定接口的实现继承.
您没有显式指定类型必须继承的接口来实例化模板.它只需要具有模板定义中使用的所有功能.但是,一切都在编译时得到解决,并编译成原始的,不可思议的十六进制数字.我称之为"编译时鸭子打字".我已经从这种心态编写了整个库,隐式模板实例化是编译时鸭子打字,并认为它是最不被重视的功能之一.
Wes*_*ley 14
结构类型系统将一个完整类型与另一个完整类型进行比较,以确定它们是否兼容.对于两种类型A
并且B
兼容,A
并且B
必须具有相同的结构 - 也就是说,on 和on上的每个方法必须具有相同的签名.A
B
鸭子打字认为两种类型对于手头的任务是等效的,如果他们都可以处理该任务.对于两种类型A
并且B
等同于想要写入文件的一段代码,A
并且B
两者都必须实现write方法.
结构类型系统比较每个方法签名(整个结构).Duck输入比较与特定任务相关的方法(与任务相关的结构).
Dar*_*rio 10
鸭子打字意味着如果它恰到好处,那就没关系
这适用于动态类型
def foo obj
obj.quak()
end
Run Code Online (Sandbox Code Playgroud)
或静态类型的编译语言
template <typename T>
void foo(T& obj) {
obj.quak();
}
Run Code Online (Sandbox Code Playgroud)
关键在于,在两个示例中,没有关于给定类型的任何信息.就在使用时(在运行时或编译时!),检查类型,如果满足所有要求,代码就可以工作.值在声明时没有明确的类型.
结构类型依赖于显式键入您的值,就像通常一样 - 区别在于具体类型不是通过继承来识别,而是通过它的结构来识别.
上面例子的结构类型代码(Scala风格)将是
def foo(obj : { def quak() : Unit }) {
obj.quak()
}
Run Code Online (Sandbox Code Playgroud)
不要将此与诸如OCaml之类的结构类型语言将其与类型推断相结合,以防止我们明确定义类型.
我不确定它是否真的能回答你的问题,但......
模板化的C++代码看起来非常类似于duck-typing,但它是静态的,编译时的,结构化的.
template<typename T>
struct Test
{
void op(T& t)
{
t.set(t.get() + t.alpha() - t.omega(t, t.inverse()));
}
};
Run Code Online (Sandbox Code Playgroud)
我的理解是类型推断器等使用结构类型来确定类型信息(想想Haskell或OCaml),而鸭子类型本身并不关心"类型",只是事物可以处理特定的方法调用/属性访问等(想想respond_to?
在Ruby或Javascript中的功能检查).
某些编程语言总会有违反某些术语定义的例子.例如,ActionScript支持在技术上不动态的实例上执行鸭子类型样式编程.
var x:Object = new SomeClass();
if ("begin" in x) {
x.begin();
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们测试了"x"中的对象实例在调用它之前是否有一个方法"begin"而不是使用接口.这在ActionScript中有效,并且几乎是鸭子类型,即使类SomeClass()本身可能不是动态的.
归档时间: |
|
查看次数: |
3837 次 |
最近记录: |