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 None jest . |
Some |
'T option |
Statyczny element członkowski, który tworzy opcję, która ma wartość, która nie None jest . |
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.ArgumentException
wartość .
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.exists
Option.forall
Option.foldBack
, , , Option.fold
i 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
.