最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

使用 F#中的度量单位保障数据类型安全

  • 2016-04-01
  • 本文字数:1027 字

    阅读完需:约 3 分钟

F#中的度量单位使得给基本数据类型添加类型信息变为可能。这将会降低单位不匹配的可能性,增加更多的安全性,例如在预期单位为毫秒的情况下调用秒。虽然可以使用类来处理度量单位不匹配,在语言中直接内置功能可以使代码变得更加简洁。

F#中的度量单位可用来给任何与其他类型相关的值,增加类型安全性。以下的代码展示了不同类型值的计算:

复制代码
[<Measure>] type dollar
[<Measure>] type pound
[<Measure>] type hour
[<Measure>] type week
[<Measure>] type year
let hoursBilledPerWeek = 32.0<hour/week>
let weeksWorkedPerYear = 47.0<week/year>
let dollarsPerHour = 100.0<dollar/hour>
let exchangeRate = 1.45<dollar/pound>
let poundsPerYear = dollarsPerHour * hoursBilledPerWeek * weeksWorkedPerYear / exchangeRate
// the value and type of poundsPerYear is: float<pound/year> = 103724.1379

一些 APIs 也可以受益于度量单位。它可以隔离一些类型的错误,例如将错误的度量单位作为参数传递。例如说 Thread.Sleep(10) 这个例子中,函数接收了一个整型参数,这个单元在之前的代码中进行过定义。使用度量单位,方法被封装之后就能提供更严密的 API:

复制代码
let sleep (time : int<ms>) = Thread.Sleep(time / 1<ms>)
sleep 10<ms>

由于上面所定义的是毫秒单位,所以调用 10 秒 sleep 就会发生编译错误:

复制代码
Error Type mismatch. Expecting a
int<ms>
but given a
int<s>

时间的单位经常需要转换。在一个公式内使用乘除法就可以完成转换。转换可以使用静态成员完成,如下面的代码所示:

复制代码
[<Measure>] type ft
[<Measure>] type inch = static member perFoot = 12.0<inch/ft>
let inches = 1.0<ft> * inch.perFoot;

处理物理问题的应用程序会需要表示一些复杂的单位,比如说牛顿。下面的例子展示了如何使用复合度量单位,组合几个简单的单位:

复制代码
let distance = 1.0<m>
let time = 2.0<sec>
let speed = 2.0<m/sec>
let acceleration = 2.0<m/sec^2>
let force = 5.0<kg m/sec^2>

需要附加说明的是,F#的度量单位不能作为公共 API 在其他.NET 语言,例如 C#中调用。这是因为度量单位不在 CLR 中,它们是作为语言结构被存储在程序集元数据中的。

查看英文原文 Type Satety for Numerics in F# Using Units of Measure


感谢张龙对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-04-01 19:00820
用户头像

发布了 218 篇内容, 共 64.9 次阅读, 收获喜欢 75 次。

关注

评论

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

听GPT 讲Deno源代码(8)

fliter

MySQL之优化SELECT语句

百度搜索:蓝易云

MySQL Linux 运维 云服务器 select

低代码与MES系统相结合

万界星空科技

低代码 低代码开发 低代码平台 mes 万界星空科技

汽车零部件MES系统实施方案

万界星空科技

汽车 mes 万界星空科技 汽车零部件

php作业1

大肚皮狒狒

2023年总结

wood

阿里云-负载均衡(ALB)

智慧源点

ALB

git生成change-id的解决方法

百度搜索:蓝易云

git 云计算 Linux 运维 云服务器

Parallels Desktop 19 for Mac(PD19虚拟机)无需关闭sipv19.1.0一键激活版

iMac小白

如何在Linux中设置SSH无密码登录

百度搜索:蓝易云

云计算 Linux 运维 SSH 云服务器

【Linux】DNS系统,ICMP协议,NAPT技术详解

百度搜索:蓝易云

云计算 Linux 运维 DNS ICMP

听GPT 讲Deno源代码(5)

fliter

SpringBoot中最常用的5个内置对象

百度搜索:蓝易云

云计算 Linux 运维 Spring Boot 云服务器

听 GPT 讲 Deno 源代码 (9)

fliter

汽车零部件MES系统解决方案

万界星空科技

汽车 制造业 mes 万界星空科技 汽车零部件

数据所在,计算随行:Databend 的 2023 年度总结

Databend

用 Go 语言实现刘谦 2024 春晚魔术,还原尼格买提汗流浃背的尴尬瞬间!

江湖十年

golang 算法

记忆承载

玄兴梦影

听GPT 讲Deno源代码(4)

fliter

vben Admin 01- 安装,初始设置

麦兜

听GPT 讲Deno源代码(7)

fliter

docker部署ELK8.8.1集群logstash报错PKIX path building failed

百度搜索:蓝易云

Linux 运维 Logstash ELK 云服务器

Go项目中的Labels

fliter

听GPT 讲Deno源代码(6)

fliter

归乡

fliter

听 GPT 讲 Deno 源代码 (10)

fliter

文心一言 VS 讯飞星火 VS chatgpt (198)-- 算法导论14.3 6题

福大大架构师每日一题

福大大架构师每日一题

认识mysql命令

百度搜索:蓝易云

MySQL 云计算 Linux 运维 云服务器

java环境搭建Ubuntu Linux教程

百度搜索:蓝易云

Java Linux ubuntu 运维 云服务器

田螺

fliter

Ubuntu 20.04通过udev规则修改网卡名称(例如eth0)

百度搜索:蓝易云

Linux ubuntu 运维 云服务器 udev

使用F#中的度量单位保障数据类型安全_.NET_Pierre-Luc Maheu_InfoQ精选文章