共用方式為


選項

當具名值或變數的實際值可能不存在時,就會使用 F# 中的選項類型。 選項具有基礎類型,而且可以保存該類型的值,或可能沒有值。

備註

下列程式代碼說明會產生選項類型的函式。

let keepIfPositive (a: int) = if a > 0 then Some(a) else None

如您所見,如果輸入 a 大於 0,則會產生 Some(a)。 否則,會產生 None

當選項沒有實際值時,會使用值 None。 否則,表達式 Some( ... ) 提供選項值。 SomeNone 的值在模式比對方面很有用,如下列函式 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。 根據不同情況,攔截例外狀況而不是讓它傳播,可能不是一個合適的設計選擇。

此外,仍然可以將 null 或 null 的值傳遞給選項的 Some 案例。 在例行的 F# 程式設計中,這通常是要避免的,但由於 .NET 中參考型別的本質,這種情況還是有可能發生。

選項屬性和方法

選項類型支援下列屬性和方法。

屬性或方法 類型 描述
None 'T option 靜態成員,建立具有 None 值的選項值。
IsNone bool 如果選項具有 None 值,則傳回 true
IsSome bool 如果 選項的值不是 None,則傳回 true
Some 'T option 建立選項的靜態成員,其值不是 None
'T 如果值是None,則拋出System.NullReferenceException,否則返回其基礎值。

選項模組

有一個模組 Option,其中包含在選項上執行作業的實用函式。 某些函式會重複屬性的功能,但在需要函式的內容中很有用。 Option.isSomeOption.isNone 都是測試選項是否保留值的模組函式。 Option.get 會取得值,如果有的話。 如果沒有值,則會擲回 System.ArgumentException

Option.bind 函式會在值上執行函式,如果有值。 函式必須只接受一個自變數,而且其參數類型必須是選項類型。 函式的傳回值是另一種選項類型。

選項模組也包含與清單、陣列、序列和其他集合類型可用函式相對應的函式。 這些函式包括 Option.mapOption.iterOption.forallOption.existsOption.foldBackOption.foldOption.count。 這些函式可讓選項像零或一個元素的集合一樣使用。 如需詳細資訊和範例,請參閱 清單中的集合函式討論。

轉換成其他類型

選項可以轉換成清單或陣列。 當選項轉換成這些數據結構之一時,產生的數據結構有零個或一個元素。 若要將選項轉換成陣列,請使用 Option.toArray。 若要將選項轉換成清單,請使用 Option.toList

帶預設值的選項轉換

除了轉換成清單和數位之外,您也可以使用 Option.defaultValue 函式提供預設值,將選項轉換成其他類型。 當您想確保值不是 None時,這特別有用。 例如:

let optionString = Some("F#")
let defaultString = optionString |> Option.defaultValue ""
// defaultString is "F#"

let optionInt = None
let defaultInt = optionInt |> Option.defaultValue 0
// defaultInt is 0

Option.defaultValue 函式可讓您順暢地處理 SomeNone 案例,而不需要模式比對。

另請參閱