BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

F#中的静态Duck Typing

| 作者 赵劼 关注 4 他的粉丝 发布于 2009年6月17日. 估计阅读时间: 5 分钟 | Google、Facebook、Pinterest、阿里、腾讯 等顶尖技术团队的上百个可供参考的架构实例!

Duck Typing是动态语言的重要特性之一,据Wikipedia中的定义,这个名称及概念由James Whitcomb Riley提出:

当一只鸟走路像鸭子,游泳像鸭子,叫起来也像鸭子,那么我们就认为它就是鸭子。

对于传统的静态类型的语言(如C#或Java),类型的判定会在编译期进行,如果一系列类型需要对外界释放出某种共同的行为,那么它们则必须符合一个共同的协议(如基类或接口)。在支持Duck Typing的语言(如JavaScript或Python)中,对于某个对象成员的访问会在运行时进行检查,正所谓“延迟判定”。关于Duck Typing的优劣,动态检查和静态检查之间的讨论已经数不胜数。

如果在C#等静态语言中希望实现Duck Typing一般都会借助反射或动态生成适配器的方式进行,而在C# 4.0中甚至增加了dynamic关键字从语法层面实现了Duck Typing。不过在F#中实现了一种在编译期进行检查的Duck Typing特性。Matthew Podwysocki在他的文章中展示了这样一个例子:

let inline flyAndWalk arg =
  let flying = ( ^a : (member Fly : unit -> string) arg)
  let walking = ( ^a : (member Walk : unit -> string) arg)
  (flying, walking)

type Duck() =
  member this.Swim() = "paddling"
  member this.Fly() = "flapping"
  member this.Walk() = "waddling"
 
type Eagle() =
  member this.Fly() = "soaring"
  member this.Walk() = "creeping"

let (eFly, eWalk) = flyAndWalk (new Eagle())
let (dFly, dWalk) = flyAndWalk (new Duck())

在以上代码中,flyAndWalk方法限制了arg参数所必须具备的条件:“拥有特定签名的Fly和Walk方法”,而编译器则会对flyAndWalk方法的使用进行校验。F#提供了inline关键字使一个函数在编译时内联至调用方,不过它也限制了此类方法被.NET平台上的其他语言调用。此外,与“范型”在运行时生成新类型的方式有所不同,“^”符号表示在编译期对可变类型进行静态解析。有关inline和“^”符号的含义及作用,Michael Giagnocavo文章对此有较为详细的解释及相关示例。

F#的强类型Duck Typing特性在编译期限制了可用类型的结构,在保证了类型安全的同时,避免使用特定的协议来强制约束不同的类型。在OCaml、Scala等语言中,类似的特性也被称作Structure Typing。Lmeyerov认为

Duck typing看上去包含了动态的含义,而Structure subtyping是Ocaml静态世界中的瑰宝。

laogao也有类似的看法:

我觉得严格意义上我们不应该称其为duck typing,而是用structural typing,只是在跟别人解释的时候,也许可以说它类似动态语言如Python、Ruby、Groovy等中的duck typing的概念。“duck typing”这个概念还是留给动态语言吧,让它指代在运行期而非编译期对类型的判定,静态语言如Scala,还是叫“structural typing”吧。

您会在什么情况下使用这个特性呢?F#作为集成至VS 2010中的一线语言,已经展现出越来越强的生命力,您准备好了吗?

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT