13.4.2.1 使用计量单位

728 篇文章 1 订阅
349 篇文章 0 订阅

13.4.2.1 使用计量单位

在 F# 中,使用计量单位很容易,这就是为什么我们在这一章看只是简单地介绍一下的原因。声明计量使用 type 关键字,加专有的特性。严格地说,计量并不是类型,但我们可以将其用作为另一种类型的部分使用。我们首先定义两个简单的计量,表示公里和小时:

[<Measure>] type km
[<Measure>] type h

可以发现,使用 Measure 特性描述的类型是计量。这是一个专有特性,F# 编译器能够理解。我们不一定要自己定义单位,可以使用 FSharp.PowerPack.dll 库中的标准集,但是现在,我们将自己声明。有了单位 km 和 h 以后,就可以创建表示公里或小时的值了。清单 13.15 显示了创建带单位的值,并写一个函数,用这些参与计算。

清单13.15 使用计量单位的计算 (F#)

> let length = 9.0<km>;;     [1]
val length : float<km> = 9.0

> length * length;;     [2]
val it : float<km^2> = 81.0

> let distanceInTwoHours(speed:float<km/h>) =     [3]
   speed * 2.0<h>;; 
val distanceInTwoHours : float<km/h> -> float<km>    [4]

> distanceInTwoHours(30.0<km/h>);; 
val it : float<km> = 60.0

描述数值常量的单位时,值的后面加上括在尖括号角中的单位[1]。我们首先定义了一个表示在长度的值,以公里计。如果计算使用带单位的值,F# 能自动推断出结果的单位,因此,可以发现,距离乘了两次,得出的面积以平方公里计[2]。描述单位时,可以使用常规表示,即,用 ^ 表示乘方,用 / 表示除法,乘法写成并列单位。
下一个示例表明,函数的参数可以包括单位信息。我们的示例函数的参数为速度,返回两小时行走的路程[3]。我们指定参数以公里每小时计,因此,增加了包含单位的类型注解,把单位放在尖括号中,与指定类型参数值时的方式相同,比如 list 类型。F# 编译器能够推断出返回的类型[4],就像处理普通类型一样。通常,当我们阅读代码时,能够为我们理解函数功能提供线索;另外,这也是写函数时重要的检查,可以避免犯低级错误:如果我们试图计算距离,但最后返回类型的单位是时间,那就肯定错了。
在世界银行的数据中,我们将使用 km^2 表示国家总面积的单位。到目前为止,一切顺利,但是,我们想要的第二个指标是以百分比的形式提供的,那么,应该如何指定百分比的单位呢?虽然,计量单位主要是用来表示物理量的,但也可以用它们来表示百分比:

[<Measure>] type percent
let coef = 33.0<percent>

这段代码创建表示百分比的单位,然后,定义了常量 coef,是值的 33%。严格地说,以百分比计的值没有单位,因为,这是一个系数,把它定义成单位很有用。为了演示,我们计算 50 公里距离的 33%。由于 coef 表示系数,可以简单地把两个值乘起来:

> 50.0<km> * coef;;
val it : float<km percent> = 1650.0

很明显这是错误的。我们期望的结果以公里计,但是,从推导出的类型可以发现,结果是以公里乘以新的单位 percent。另外,从交互运行的代码还可以看到,数值太大,而计量单位的重要性就在于,我们可以在类型检查期间就发现错误,而不必等到程序实际运行时。那么,哪里出问题了呢?百分比值表示系数乘以 100;要正确写出计算,需要把值除以 100 percent:

> 50.0<km> * coef / 100.0<percent>;;
val it : float<km> = 16.5

可以发现,现在好多了。结果除以 100 percent,这样,在结果中就没有 percent单位了。F# 自动化简单位,知道 km percent/percent 等于 km。此示例演示了使用计量单位的重要原因:就像其他类型一样,能够有帮于尽早捕获大量的错误。

注意

计量单位还有很多其他重要的功能,在这个简介中我们没有涉及到。例如,可以定义派生单位,比如 N(表示力,以牛顿计),这实际上就是 kg m/s^2;在函数或类型中,泛型类型参数使用单位,也是可能的。有关计量单位的详细信息,请参阅 F# 联机文档,和架构师 Andrew Kennedy 关于该功能的博客(http://blogs.msdn.com/andrewkennedy)。

现在,我们回到主要的示例,把下载的数据转换成有单位的类型化形式。我们将使用原子单位 percent 表示地区森林覆盖,用单位 km^2 表示面积。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值