Alternativ
Alternativtypen i F# används när ett faktiskt värde kanske inte finns för ett namngivet värde eller en variabel. Ett alternativ har en underliggande typ och kan innehålla ett värde av den typen, eller så kanske det inte har något värde.
Kommentarer
Följande kod illustrerar en funktion som genererar en alternativtyp.
let keepIfPositive (a: int) = if a > 0 then Some(a) else None
Som du ser genereras om indata a
är större än 0 Some(a)
. Annars None
genereras.
Värdet None
används när ett alternativ inte har något verkligt värde. Annars ger uttrycket Some( ... )
alternativet ett värde. Värdena Some
och None
är användbara i mönstermatchning, som i följande funktion exists
, som returnerar true
om alternativet har ett värde och false
om det inte gör det.
let exists (x: int option) =
match x with
| Some(x) -> true
| None -> false
Använda alternativ
Alternativ används ofta när en sökning inte returnerar ett matchande resultat, vilket visas i följande kod.
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 ]
I föregående kod genomsöks en lista rekursivt. Funktionen tryFindMatch
använder en predikatfunktion pred
som returnerar ett booleskt värde och en lista att söka i. Om ett element som uppfyller predikatet hittas slutar rekursionen och funktionen returnerar värdet som ett alternativ i uttrycket Some(head)
. Rekursionen slutar när den tomma listan matchas. Då har värdet head
inte hittats och None
returneras.
Många F#-biblioteksfunktioner som söker i en samling efter ett värde som kanske eller kanske inte finns returnerar option
typen. Enligt konventionen börjar dessa funktioner med prefixet try
, Seq.tryFindIndex
till exempel .
Alternativ kan också vara användbara när ett värde kanske inte finns, till exempel om det är möjligt att ett undantag utlöses när du försöker konstruera ett värde. Följande kodexempel illustrerar detta.
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
Funktionen openFile
i föregående exempel har typen string -> File option
eftersom den returnerar ett File
objekt om filen öppnas och None
om ett undantag inträffar. Beroende på situationen kanske det inte är ett lämpligt designval att fånga ett undantag i stället för att tillåta att det sprids.
Dessutom är det fortfarande möjligt att skicka null
eller ett värde som är null för Some
ett alternativ. Detta är vanligtvis att undvika och är vanligtvis i rutinmässig F#-programmering, men är möjligt på grund av typen av referenstyper i .NET.
Alternativegenskaper och -metoder
Alternativtypen stöder följande egenskaper och metoder.
Egenskap eller metod | Typ | Beskrivning |
---|---|---|
None |
'T option |
En statisk medlem som skapar ett alternativvärde som har värdet None . |
IsNone | bool |
Returnerar true om alternativet har värdet None . |
IsSome | bool |
Returnerar true om alternativet har ett värde som inte None är . |
Some |
'T option |
En statisk medlem som skapar ett alternativ som har ett värde som inte None är . |
Värde | 'T |
Returnerar det underliggande värdet eller genererar ett System.NullReferenceException om värdet är None . |
Alternativmodul
Det finns en modul, Alternativ, som innehåller användbara funktioner som utför åtgärder på alternativ. Vissa funktioner upprepar egenskapernas funktioner men är användbara i kontexter där en funktion behövs. Option.isSome och Option.isNone är båda modulfunktioner som testar om ett alternativ innehåller ett värde. Option.get hämtar värdet, om det finns ett. Om det inte finns något värde genererar System.ArgumentException
det .
Funktionen Option.bind kör en funktion på värdet om det finns ett värde. Funktionen måste ha exakt ett argument och dess parametertyp måste vara alternativtypen. Returvärdet för funktionen är en annan alternativtyp.
Alternativmodulen innehåller även funktioner som motsvarar de funktioner som är tillgängliga för listor, matriser, sekvenser och andra samlingstyper. Dessa funktioner omfattar Option.map
, Option.iter
, Option.forall
, Option.exists
, Option.foldBack
, Option.fold
och Option.count
. Med de här funktionerna kan alternativ användas som en samling med noll eller ett element. Mer information och exempel finns i diskussionen om samlingsfunktioner i Listor.
Konvertera till andra typer
Alternativ kan konverteras till listor eller matriser. När ett alternativ konverteras till någon av dessa datastrukturer har den resulterande datastrukturen noll eller ett element. Om du vill konvertera ett alternativ till en matris använder du Option.toArray
. Om du vill konvertera ett alternativ till en lista använder du Option.toList
.