5.3.2.1 用 F# 匹配差别联合

来源:互联网 发布:淘宝上送的优酷会员 编辑:程序博客网 时间:2024/06/06 01:58

5.3.2.1 用 F# 匹配差别联合

 

当使用差别联合时,必须要处理所有可能的选项,因为,我们不知道这个值到底表示哪一个选项。回忆一下以前类似的情况,处理列表时,问题要检查列表是否为空,我们是使用模式匹配实现的:match 构造能够根据几种模式检查值。我们可以用同样的功能,处理差别联合,只是这里模式换成了识别器。清单 5.5 是获取计划事件下一次发生时间的示例。

 

清单 5.5 计算事件的下一次发生 (F#)

let getNextOccurrence(schedule) =

  matchschedule with

  |Never -> DateTime.MaxValue  [1]

  |Once(eventDate) –>    [2]

    if(eventDate > DateTime.Now) then eventDate

    elseDateTime.MaxValue

  |Repeatedly(startDate, interval) –>   [3]

    letsecondsFromFirst = (DateTime.Now - startDate).TotalSeconds

    let q = secondsFromFirst /interval.TotalSeconds  | [4]

    letq = max q 0.0                           |

    startDate.AddSeconds

     (interval.TotalSeconds * (Math.Floor(q) + 1.0))

 

这个示例是有点复杂,但它展示了F# 程序的典型结构。我们使用标准 .NET DateTime 和 TimeSpan 结构处理日期和时间;使用模式匹配检查已经选择了哪一个计划。第一种情况[1],返回 DateTime.MaxValue,这是一个特殊值,用来表示事件在未来所有日期都没有计划;第二种情况[2],如果事件还没有发生,则返回事件日期;最后一种情况(重复事件)更复杂[3],我们首先计算过去已经发生了多少次事件,返回下一次发生的时间。可以看到,我们在代码中两次声明 q 值[4],这称为隐藏值(hiding a value),如果我们想把复杂的计算拆成两个或更多个步骤,这是很有用的,可以确保我们不会意外地使用中间值。

可以发现,用于检查值是否值匹配特定的识别器的模式,与我们在前面用于构造值的模式完全相同;模式也提取保存的值作为参数值,指定给新的值(分别是 eventDate 和带 interval 的 startDate),这样,我们就可以立即使用它们。

0 0
原创粉丝点击