【QCon】精华内容上线92%,全面覆盖“人工智能+”的典型案例!>>> 了解详情
写点什么

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

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

关注

评论

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

推动数字化转型,OceanBase 助力保险企业创造新价值

OceanBase 数据库

数据库 开源 技术宅 oceanbase 分布式,

第三代分布式数据库来了,真香!

OceanBase 数据库

数据库 开源 分布式 oceanbase

双11“剁手”后,你的包裹收到了吗?

OceanBase 数据库

数据库 开源 分布式 oceanbase

黑客常备20个工具,你知道几个?

喀拉峻

Prometheus 都可以采集那些指标?-- 常用 Exporter 合集

耳东@Erdong

内容合集

运维体系建设思考-稳定性篇

ning

运维 云原生 监控 稳定性

MySQL事务的实现原理之Undo Log的分析

卢卡多多

Undo Log 11月日更

🎅Less快速学习(下)🎅

空城机

CSS 大前端 less 11月日更

【Three.js】随着元宇宙开启WEB3D之路

devpoint

JavaScript WebGL 3D three.js 11月日更

千万级学生管理系统的考试试卷存储方案设计

Beyond Ryan

深入浅出,一文吃透mysql索引

微客鸟窝

MySQL 11月日更

Prometheus Exporter (三)容器信息监控

耳东@Erdong

container Prometheus exporter 11月日更 cAdvisor

太顶了!华为高工用一份423页的网络协议笔记把计算机网络讲清了

热爱java的分享家

Java 架构 面试 编程语言 网络协议

度小满启动“小微加油站”,让低息服务可持续

脑极体

阿里大规模业务混部下的全链路资源隔离技术演进

阿里巴巴云原生

阿里云 云原生 资源隔离 ACK 混部

【死磕Java并发】-----Java内存模型之总结

chenssy

11月日更 死磕 Java 死磕 Java 并发

惨遭GitHub直接封杀的阿里P8手敲出来这份565页凤凰架构分布式手册,有何神奇之处

热爱java的分享家

Java 面试 程序人生 编程语言 凤凰架构

给面试官上一课:HTTPS是先进行TCP三次握手,再进行TLS四次握手

热爱java的分享家

Java 架构 程序人生 编程语言 经验分享

我理解的CPI和PPI

石云升

学习笔记 11月日更

家庭太阳能发电,何时能告别“两极分化”?

脑极体

“敏捷版”全链路压测

阿里巴巴云原生

阿里云 云原生 全链路压测 PTS

🍃【Spring专题】「实战系列」重新回顾一下异常重试框架Spring Retry的功能指南

洛神灬殇

spring 11月日更 Spring retry Guava retry

Go 的 Panics 处理

baiyutang

golang 11月日更

FFmpeg[5] - 将视频文件转码成MP4格式(FFmpeg转封装2)

liuzhen007

11月日更

Python Qt GUI设计:QLabel标签类(基础篇—11)

不脱发的程序猿

Python PyQt GUI设计 QLabel标签类

参与tdengine开源的方式

williamcai

fork git 学习

[Pulsar] ChunkMessageID介绍及其原理

Zike Yang

Apache Pulsar 11月日更

前端开发:VS Code编辑器新建Vue文件自定义模板的方法

三掌柜

11月日更

共建全栈国产化解决方案 | OceanBase持续与合作伙伴推进测试互认

OceanBase 数据库

数据库 分布式 双十一 oceanbase

两个排序数组的中位数,“最”有技术含量的解法!

老表

Python 算法 LeetCode 11月日更

.NET6新东西--Lambda优化

喵叔

11月日更

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