Freigeben über


Optionen

Der Optionstyp in F# wird verwendet, wenn möglicherweise kein tatsächlicher Wert für einen benannten Wert oder eine Variable vorhanden ist. Eine Option weist einen zugrunde liegenden Typ auf und kann einen Wert dieses Typs enthalten, oder sie hat möglicherweise keinen Wert.

Bemerkungen

Der folgende Code veranschaulicht eine Funktion, die einen Optionstyp generiert.

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

Wie Sie sehen können, wird Some(a) generiert, wenn die Eingabe a größer als 0 ist. Andernfalls wird None generiert.

Der Wert None wird verwendet, wenn eine Option keinen tatsächlichen Wert aufweist. Andernfalls gibt der Ausdruck Some( ... ) der Option einen Wert. Die Werte Some und None eignen sich für den Musterabgleich, wie in der folgenden Funktion exists, die true zurückgibt, wenn die Option einen Wert aufweist und false, wenn dies nicht der Fall ist.

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

Verwenden von Optionen

Optionen werden häufig verwendet, wenn eine Suche kein übereinstimmende Ergebnis zurückgibt, wie im folgenden Code gezeigt.

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 ]

Im vorherigen Code wird eine Liste rekursiv durchsucht. Die Funktion tryFindMatch verwendet eine Prädikatfunktion pred, die einen booleschen Wert zurückgibt, und eine Liste zum Durchsuchen. Wenn ein Element gefunden wird, das dem Prädikat entspricht, endet die Rekursion, und die Funktion gibt den Wert als Option im Ausdruck Some(head)zurück. Die Rekursion endet, wenn die leere Liste übereinstimmt. An diesem Punkt wurde der Wert head nicht gefunden, und None wird zurückgegeben.

Viele F#-Bibliotheksfunktionen, die eine Sammlung nach einem Wert durchsuchen, der möglicherweise vorhanden ist oder nicht, geben den option Typ zurück. In der Konvention beginnen diese Funktionen mit dem Präfix try, z. B. Seq.tryFindIndex.

Optionen können auch hilfreich sein, wenn ein Wert möglicherweise nicht vorhanden ist, z. B. wenn eine Ausnahme ausgelöst wird, wenn Sie versuchen, einen Wert zu erstellen. Im folgenden Codebeispiel wird dies veranschaulicht.

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

Die openFile-Funktion im vorherigen Beispiel weist typ string -> File option auf, da sie ein File Objekt zurückgibt, wenn die Datei erfolgreich geöffnet wird, und None, wenn eine Ausnahme auftritt. Je nach Situation kann es sich nicht um eine geeignete Entwurfsentscheidung handeln, eine Ausnahme abzufangen, anstatt sie weiterlaufen zu lassen.

Darüber hinaus ist es weiterhin möglich, null oder einen Wert, der null ist, an den Some Fall einer Option zu übergeben. Dies ist im Allgemeinen zu vermeiden und befindet sich in der Regel in der Routine-F#-Programmierung, ist jedoch aufgrund der Art von Verweistypen in .NET möglich.

Optionseigenschaften und -methoden

Der Optionstyp unterstützt die folgenden Eigenschaften und Methoden.

Eigenschaft oder Methode Typ Beschreibung
None 'T option Ein statisches Element, das einen Optionswert erstellt, der den None Wert aufweist.
IsNone bool Gibt true zurück, wenn die Option den wert None hat.
IsSome bool Gibt true zurück, wenn die Option einen Wert aufweist, der nicht Noneist.
Some 'T option Ein statisches Element, das eine Option erstellt, die einen Wert aufweist, der nicht Noneist.
Wert 'T Gibt den zugrunde liegenden Wert zurück oder löst eine System.NullReferenceException aus, wenn der Wert Noneist.

Optionsmodul

Es gibt ein Modul, Option, das nützliche Funktionen enthält, die Vorgänge für Optionen ausführen. Einige Funktionen wiederholen die Funktionalität der Eigenschaften, sind aber in Kontexten nützlich, in denen eine Funktion benötigt wird. Option.isSome und Option.isNone sind beide Modulfunktionen, die testen, ob eine Option einen Wert enthält. Option.get erhält den Wert, falls einer vorhanden ist. Wenn kein Wert vorhanden ist, wird System.ArgumentExceptionausgelöst.

Die Option.bind Funktion führt eine Funktion für den Wert aus, wenn ein Wert vorhanden ist. Die Funktion muss genau ein Argument annehmen, und der Parametertyp muss der Optionstyp sein. Der Rückgabewert der Funktion ist ein anderer Optionstyp.

Das Optionsmodul enthält auch Funktionen, die den Funktionen entsprechen, die für Listen, Arrays, Sequenzen und andere Sammlungstypen verfügbar sind. Zu diesen Funktionen gehören Option.map, Option.iter, Option.forall, Option.exists, Option.foldBack, Option.foldund Option.count. Diese Funktionen ermöglichen die Verwendung von Optionen wie eine Auflistung von null oder einem Element. Weitere Informationen und Beispiele finden Sie in der Erläuterung von Sammlungsfunktionen in Listen.

Konvertieren in andere Typen

Optionen können in Listen oder Arrays konvertiert werden. Wenn eine Option in eine dieser Datenstrukturen konvertiert wird, weist die resultierende Datenstruktur null oder ein Element auf. Verwenden Sie Option.toArray, um eine Option in ein Array zu konvertieren. Verwenden Sie Option.toList, um eine Option in eine Liste zu konvertieren.

Optionen für die Konvertierung mit Standardwerten

Zusätzlich zum Konvertieren in Listen und Arrays können Optionen in andere Typen konvertiert werden, indem Standardwerte mithilfe der Option.defaultValue-Funktion bereitgestellt werden. Dies ist besonders hilfreich, wenn Sie sicherstellen möchten, dass der Wert nicht Noneist. Zum Beispiel:

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

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

Mit der Option.defaultValue-Funktion können Sie sowohl Some als auch None Fälle nahtlos ohne Musterabgleich behandeln.

Siehe auch