HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

F#中的静态 Duck Typing

  • 2009-06-15
  • 本文字数:1339 字

    阅读完需:约 4 分钟

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 在他的文章中展示了这样一个例子:

复制代码
<span>let inline </span>flyAndWalk arg =
<span>let </span>flying = ( ^a : (<span>member </span>Fly : unit <span>-> </span>string) arg)
<span>let </span>walking = ( ^a : (<span>member </span>Walk : unit <span>-> </span>string) arg)
(flying, walking)
<span>type </span>Duck() =
<span>member </span>this.Swim() = <span>"paddling"
</span><span>member </span>this.Fly() = <span>"flapping"
</span><span>member </span>this.Walk() = <span>"waddling"
</span><span>type </span>Eagle() =
<span>member </span>this.Fly() = <span>"soaring"
</span><span>member </span>this.Walk() = <span>"creeping"
</span><span>let </span>(eFly, eWalk) = flyAndWalk (<span>new </span>Eagle())
<span>let </span>(dFly, dWalk) = flyAndWalk (<span>new </span>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 中的一线语言,已经展现出越来越强的生命力,您准备好了吗?

2009-06-15 22:451437
用户头像

发布了 157 篇内容, 共 54.6 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

week13 作业

雪涛公子

为微服务建一个简约而不简单的配置中心

架构师修行之路

微服务 etcd 配置中心

PageRank算法

技术小生

详解 Python 的二元算术运算,为什么说减法只是语法糖?

Python猫

Python 编程 翻译

Linux Shell编程

yuanhang

Shell

甲方日常 11

句子

工作 随笔杂谈 日常

打破Scrum的五个误区(译)

Bruce Talk

Scrum 敏捷开发 Agile

Centos7 IP、名字、防火墙配置

yuanhang

centos7 防火墙 静态IP

【架构师训练营】第 13周作业

花生无翼

大数据解答(二)

dony.zhang

数据分析

week13 总结

雪涛公子

架构师训练营第十三章作业

吴吴

第十三周

Acker飏

第十三周作业

Linuxer

week13学习总结

burner

你所在的行业,常用的数据分析指标有哪些?

李朋

week13 homework

burner

架构师训练营 week13

devfan

初露锋芒的AI战斗机,打开AI军备竞赛的潘多拉盒子

脑极体

Go 云原生应用实战系列(二)

田晓亮

微服务 云原生 Go 语言

架构师训练营Week13作业

Frank Zeng

极客大学架构师训练营

架构师训练营Week13总结

Frank Zeng

极客大学架构师训练营

Week 13 作业

鱼_XueTr

13周作业

方堃

架构师训练营 week13 - 学习总结

devfan

【第十三周】命题作业——Google 搜索排序

赵龙

Week13 学习总结

赵龙

使用Typora+PicGo配置Gitee图床

清菡软件测试

图床

Week13

一叶知秋

大数据架构&数据应用/分析&机器学习(二)

dony.zhang

flink spark 学习 Storm

数据分析指标-电商行业

李小匪

F#中的静态Duck Typing_.NET_赵劼_InfoQ精选文章