11.2.2.1 结构相等和比较

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

11.2.2.1 结构相等和比较

 

在F# 中,我们能声明的大多数类型,都是不可变的;如果我们不显式提供实现IComparable <T> 接口,并重写 Equals 方法,F# 编译器会自动实现,它是通过比较结构相等(structural equality)实现的。对F# 的类,还不能自动完成,只对简单的函数类型,比如,记录、差别联合和元组,不必要显式声明。

使用这种比较类型的值,如果它们是相等的简单类型,比如,整数或字符串,或者是相同值的组合,使用递归地结构相等,被认为是相等的。清单11.9 演示了记录的结构相等,包含元组和基本值。

 

清单11.9 用结构相等比较记录(F# Interactive)

> type WeatherItem =

     {Temperature : int * int;

      Text : string }

   letwinter1 = { Temperature = -10, -2; Text = "Winter" }    | 创建记录

   letwinter2 = { Temperature = -10, -2; Text = "Winter" };;   | 包含相同值

(...)

 

> System.Object.ReferenceEquals(winter1,winter2);;   <-- [1] 值表示成不同的实例

val it : bool = false

 

> winter1.Equals(winter2);;  |

val it : bool = true          | [2] ...

                        | 但被认为相等

> winter1 = winter2;;       |

val it : bool = true          |

 

首先,我们声明了F# 记录类型,包含两个字段;第一个字段类型是两个整数的元组,第二个字段是字符串。我们创建了这个记录类型的两个值,每个对应字段的值完全相同。

我们可以看到,确实有两个实例:引用相等的测试[1],返回false。如果我们使用重写的Equals 方法,或者标准的F# 运算符测试相等[2],运行时将使用结构相等,报告这两个值相等。首先,两个元组值比较结构相等,然后,比较两个字符串。

正如我们前面所说,这种方法适用于记录、元组、差别联合和数组;因为不可变的F# 列表声明为差别联合,所以,可以同等对待。我们将在写单元测试期望时,使用此功能,但首先,我们要看一下另外的功能,自动生成函数。我们已经知道使用结构相等,可以测试值是否相等,而F# 还提供了结构比较(structural comparisons),可以排序:

 

> let summer = { Temperature = 10, 20; Text= "Summer" };;

(...)

 

> summer = winter1;;

val it : bool = false

 

> summer > winter1;;

val it : bool = true

 

这段代码用清单11.9 中声明的记录类型,创建了一个新的值,并与前面清单中的值进行比较。第一个结果并不奇怪:这两个值是不同的;第二个结果值得解释一下。为什么会认为summer 值比winter1 大呢?原因是,F# 编译器还为WeatherItem 类型生成了默认的比较[运算]。比较按照它们声明的顺序,使用字段的值:例如,元组值(10,0) 比(9,100) 大。这个默认行为是有益的,特别是,如果在设计自己的类型时,把它考虑进去。但本章的其余部分,我们侧重于结构相等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值