写点什么

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:451455
用户头像

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

关注

评论

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

写博客是一种乐趣,一种需要培养的乐趣,java技术架构SHEET

Java 程序员 后端

农业末流211,Java自学一年的我是怎么走上大厂之路的

Java 程序员 后端

一个往返于海陆的撸猫打渔人,用影像记录生活的星辰大海

最新动态

分布式事务与Seate框架:分布式事务理论,Java知识总结

Java 程序员 后端

全网最透彻!Dubbo整合SpringBoot详解,又通宵了

Java 程序员 后端

入门级的我在学完阿里大牛写的MySQL笔记后,简历上写了精通

Java 程序员 后端

关于垃圾回收你真的了解透彻了吗?我熬夜深度剖析了一下

Java 程序员 后端

分布式ID生成策略,我和面试官掰扯了一个小时

Java 程序员 后端

先知道怎么手写一个分页查询,再去使用PageHelper吧

Java 程序员 后端

利用这份文档,我成功定位阿里P6,却拿着P7的工资

Java 程序员 后端

利用碎片化的时间逆袭进百度,我的面试经历你敢听吗?

Java 程序员 后端

公司来了一位前阿里大神,分享8面阿里面经(Java岗面试题集锦

Java 程序员 后端

关于Redis主从节点数据过期一致性的思考,它真的足够一致了吗?

Java 程序员 后端

开源应用中心|Discuz!X全新PC社区体验,多种场景一站解决

Discuz! 开源社区 Discuz

判断对象是否已死分析总结——JVM系列,让人茅塞顿开

Java 程序员 后端

利用多condition动态管理池化的异步资源背景

Java 后端

八、springboot 简单优雅的通过docker-compose 构建

Java 程序员 后端

全网讲解最透彻:高性能网络应用框架Netty,仅此一篇

Java 程序员 后端

凭借着这份Spring面试题,我拿到了阿里,字节跳动美团的offer

Java 程序员 后端

分布式基石|最难 paxos 和最易 raft?,java排序算法面试题

Java 程序员 后端

刚从今日头条Java研发岗面试回来,我总结的失败原因(附面试题

Java 程序员 后端

我的应用我做主丨动手搭建招聘小应用

华为云开发者联盟

低代码 招聘 应用 AppCube 应用魔方

初学者这样玩 TypeScript,迟早进大厂系列!

Java 程序员 后端

初探Linux--鸟哥私房菜读书笔记,廖雪峰java教程百度云

Java 程序员 后端

凡尔赛一波:美团面试就这?,java工程师面试突击第二季分布式

Java 程序员 后端

全网最新最全面Java程序员面试清单(12专题5000解析)

Java 程序员 后端

全网火爆MySql 开源笔记,图文并茂易上手,阿里P8都说好

Java 程序员 后端

初识java-JDBC,mysql索引左前缀原理

Java 程序员 后端

做了两年P7面试官,谈谈我认为的阿里人才画像,你配吗

Java 程序员 后端

分布式下的数据一致性问题,怎么解决?,java编程教程下载

Java 程序员 后端

写了四年的Java代码,分布式高并发都不会还做程序员?

Java 程序员 后端

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