跳转到内容

F# 编程/可选类型

来自维基教科书,开放世界中的开放书籍
上一个:高阶函数 索引 下一个:元组和记录
F#:可选类型

可选类型可以保存两个可能的值:Some(x)None。可选类型通常用于表示计算中的可选值,或指示特定计算是否成功。

使用可选类型

[编辑 | 编辑源代码]

假设我们有一个将两个整数相除的函数。通常情况下,我们会按如下方式编写函数

let div x y = x / y

这个函数运行良好,但并不安全:有可能将无效值传递给此函数,导致运行时错误。以下是在 fsi 中的演示

> let div x y = x / y;;

val div : int -> int -> int

> div 10 5;;
val it : int = 2

> div 10 0;;
System.DivideByZeroException: Attempted to divide by zero.
   at <StartupCode$FSI_0035>.$FSI_0035._main()
stopped due to error

div 10 5 正常执行,但 div 10 0 会抛出除零异常。

使用可选类型,我们可以在计算成功时返回 Some(value),或在计算失败时返回 None

> let safediv x y =
    match y with
    | 0 -> None
    | _ -> Some(x/y);;

val safediv : int -> int -> int option

> safediv 10 5;;
val it : int option = Some 2

> safediv 10 0;;
val it : int option = None

请注意 divsafediv 函数之间的一个重要区别

val div : int -> int -> int
val safediv : int -> int -> int option

div 返回一个 int,而 safediv 返回一个 int option。由于我们的 safediv 函数返回不同的数据类型,因此它向客户端告知我们的函数已进入无效状态。

可选类型在概念上类似于 C# 等语言中的可空类型,但 F# 可选类型不使用 CLR System.Nullable<T> 在 IL 中表示,因为语义存在差异。

模式匹配可选类型

[编辑 | 编辑源代码]

模式匹配可选类型与创建它们一样容易:用于声明可选类型的语法也用于匹配可选类型

> let isFortyTwo = function
    | Some(42) -> true
    | Some(_) | None -> false;;

val isFortyTwo : int option -> bool

> isFortyTwo (Some(43));;
val it : bool = false

> isFortyTwo (Some(42));;
val it : bool = true

> isFortyTwo None;;
val it : bool = false

Option 模块中的其他函数

[编辑 | 编辑源代码]

val get : 'a option -> 'a

返回 Some 可选类型的 value。

val isNone : 'a option -> bool

对于 None 可选类型返回 true,否则返回 false

val isSome : 'a option -> bool

对于 Some 可选类型返回 true,否则返回 false

val map : ('a -> 'b) -> 'a option -> 'b option

对于 None 返回 None。对于 Some(x) 返回 Some(f x),其中 f 是给定的映射函数。

val iter : ('a -> unit) -> 'a option -> unit

将给定函数应用于 Some 可选类型的 value,否则不执行任何操作。
上一个:高阶函数 索引 下一个:元组和记录
华夏公益教科书