選項 (F#)
具名值或變數可能沒有實際值時,會使用 F# 中的選項型別。 選項有基礎型別,而且可以保留該型別的值,也可能沒有值。
備註
下列程式碼說明選項型別的用法。
let keepIfPositive (a : int) = if a > 0 then Some(a) else None
選項沒有實際值時,會使用 None 值。 否則,運算式 Some( ... ) 會提供值給選項。 Some 和 None 值適用於模式比對,如下列函式 exists 所示,如果選項有值則傳回 true,否則傳回 false。
let exists (x : int option) =
match x with
| Some(x) -> true
| None -> false
使用選項
搜尋未傳回相符結果時,一般會使用選項,如下列程式碼所示。
let rec tryFindMatch pred list =
match list with
| head :: tail -> if pred(head)
then Some(head)
else tryFindMatch pred tail
| [] -> None
// result1 is Some 100 and its type is int option.
let result1 = tryFindMatch (fun elem -> elem = 100) [ 200; 100; 50; 25 ]
// result2 is None and its type is int option.
let result2 = tryFindMatch (fun elem -> elem = 26) [ 200; 100; 50; 25 ]
在前一個程式碼中,會遞迴搜尋清單。 tryFindMatch 函式採用 pred 述詞函式,以傳回布林值以及要搜尋的清單。 如果找到滿足述詞的項目,則遞迴會結束,而且函式會傳回值做為 Some(head) 運算式中的選項。 找到空白清單時,會結束遞迴。 此時,如果找不到 head 值,則會傳回 None。
多個 F# 程式庫函式可用於搜尋可能存在之值的集合,而這些程式庫函式會傳回 option 型別。 按照慣例,這些函式的開頭是 try 前置詞 (例如 Seq.tryFindIndex)。
值可能不存在時 (例如,如果在您嘗試建構值時可能會擲回例外狀況),選項也十分有用。 下列程式碼範例會說明這點。
open System.IO
let openFile filename =
try
let file = File.Open (filename, FileMode.Create)
Some(file)
with
| ex -> eprintf "An exception occurred with message %s" ex.Message
None
在前一個範例中,openFile 函式具有 string -> File option 型別,因為它會在成功開啟檔案時傳回 File 物件,而在發生例外狀況時傳回 None。 根據此情況,可能不是攔截例外狀況的適當設計選擇,而是允許它傳播。
選項屬性和方法
選項型別支援下列屬性和方法。
屬性或方法 |
型別 |
描述 |
---|---|---|
'T option |
靜態屬性可讓您建立具有 None 值的選項值。 |
|
bool |
如果選項具有 None 值,則會傳回 true。 |
|
bool |
如果選項的值不是 None,則會傳回 true。 |
|
'T option |
建立具有非 None 值之選項的靜態成員。 |
|
'T |
如果值為 None,則傳回基礎值,或擲回 NullReferenceException。 |
選項模組
Option 模組包含對選項執行作業的有用函式。 部分函式會重複屬性的功能,但適用於需要函式的內容。 Option.isSome 和 Option.isNone 都是測試選項是否保留值的模組函式。 Option.get 會取得值 (如果有的話)。 如果沒有值,則會擲回 ArgumentException。
Option.bind 函式會針對值執行函式 (如果有值的話)。 此函式只能採用一個引數,而其參數型別必須是選項型別。 此函式的傳回值是另一種選項型別。
選項模組也包括函式,該函式對應於可用於清單、陣列、序列和其他集合型別的函式。 這些函式包括 Option.map、Option.iter、Option.forall、Option.exists、Option.foldBack、Option.fold 和 Option.count。 這些函式可讓選項當成具有零個或一個項目的集合使用。 如需詳細資訊和範例,請參閱清單中的集合函式討論。
轉換成其他型別
選項可以轉換成清單或陣列。 將選項轉換成上述其中一種資料結構時,產生的資料結構會有零個或一個項目。 若要將選項轉換成陣列,請使用 Option.toArray。 若要將選項轉換成清單,請使用 Option.toList。