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.tryFindIndextill 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.ArgumentExceptiondet .

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.foldoch 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.

Se även