Opcje

Typ opcji w języku F# jest używany, gdy rzeczywista wartość może nie istnieć dla nazwanej wartości lub zmiennej. Opcja ma typ bazowy i może przechowywać wartość tego typu lub może nie mieć wartości.

Uwagi

Poniższy kod ilustruje funkcję, która generuje typ opcji.

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

Jak widać, jeśli dane wejściowe a są większe niż 0, Some(a) są generowane. None W przeciwnym razie jest generowany.

Wartość None jest używana, gdy opcja nie ma rzeczywistej wartości. W przeciwnym razie wyrażenie Some( ... ) daje opcję wartości. Wartości Some i None są przydatne w dopasowywaniu wzorców, jak w poniższej funkcji exists, która zwraca true , jeśli opcja ma wartość i false jeśli nie.

let exists (x: int option) =
    match x with
    | Some(x) -> true
    | None -> false

Korzystanie z opcji

Opcje są często używane, gdy wyszukiwanie nie zwraca pasującego wyniku, jak pokazano w poniższym kodzie.

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 ]

W poprzednim kodzie lista jest wyszukiwana rekursywnie. Funkcja tryFindMatch przyjmuje funkcję pred predykatu, która zwraca wartość logiczną i listę do wyszukania. Jeśli zostanie znaleziony element spełniający wymagania predykatu, rekursja kończy się, a funkcja zwraca wartość jako opcję w wyrażeniu Some(head). Rekursja kończy się po dopasowaniu pustej listy. W tym momencie nie znaleziono wartości head i None jest zwracana.

Wiele funkcji biblioteki języka F#, które wyszukują kolekcję pod kątem wartości, która może lub nie istnieje, zwraca option typ. Zgodnie z konwencją te funkcje zaczynają się od prefiksu try , na przykład Seq.tryFindIndex.

Opcje mogą być również przydatne, gdy wartość może nie istnieć, na przykład jeśli istnieje możliwość, że podczas próby utworzenia wartości zostanie zgłoszony wyjątek. Pokazano to w poniższym przykładzie kodu.

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

Funkcja openFile w poprzednim przykładzie ma typ string -> File option , ponieważ zwraca File obiekt, jeśli plik zostanie otwarty pomyślnie i None jeśli wystąpi wyjątek. W zależności od sytuacji może nie być odpowiednim wyborem projektowym, aby przechwycić wyjątek, zamiast zezwalać na propagację.

Ponadto nadal można przekazać null wartość lub wartość, która ma wartość null w Some przypadku opcji. Zwykle należy tego uniknąć i zazwyczaj jest to rutynowe programowanie języka F#, ale jest możliwe ze względu na charakter typów referencyjnych na platformie .NET.

Właściwości i metody opcji

Typ opcji obsługuje następujące właściwości i metody.

Właściwość lub metoda Type Opis
None 'T option Statyczny element członkowski, który tworzy wartość opcji, która ma None wartość.
IsNone bool Zwraca true wartość , jeśli opcja ma None wartość .
IsSome bool Zwraca true wartość , jeśli opcja ma wartość, która nie Nonejest .
Some 'T option Statyczny element członkowski, który tworzy opcję, która ma wartość, która nie Nonejest .
Wartość 'T Zwraca wartość bazową lub zgłasza System.NullReferenceException wartość , jeśli wartość to None.

Moduł opcji

Istnieje moduł Opcja, który zawiera przydatne funkcje, które wykonują operacje na opcjach. Niektóre funkcje powtarzają funkcjonalność właściwości, ale są przydatne w kontekstach, w których potrzebna jest funkcja. Option.isSome i Option.isNone to funkcje modułu, które testują, czy opcja zawiera wartość. Metoda Option.get uzyskuje wartość, jeśli istnieje. Jeśli nie ma wartości, zgłasza System.ArgumentExceptionwartość .

Funkcja Option.bind wykonuje funkcję na wartości, jeśli istnieje wartość. Funkcja musi przyjmować dokładnie jeden argument, a jego typ parametru musi być typem opcji. Zwracana wartość funkcji jest innym typem opcji.

Moduł opcji zawiera również funkcje, które odpowiadają funkcjom dostępnym dla list, tablic, sekwencji i innych typów kolekcji. Te funkcje obejmują Option.map, , Option.iter, Option.existsOption.forallOption.foldBack, , , Option.foldi Option.count. Te funkcje umożliwiają korzystanie z opcji, takich jak kolekcja zero lub jeden element. Aby uzyskać więcej informacji i przykładów, zobacz omówienie funkcji kolekcji na listach.

Konwertowanie na inne typy

Opcje można konwertować na listy lub tablice. Gdy opcja jest konwertowana na jedną z tych struktur danych, wynikowa struktura danych ma zero lub jeden element. Aby przekonwertować opcję na tablicę, użyj polecenia Option.toArray. Aby przekonwertować opcję na listę, użyj polecenia Option.toList.

Zobacz też