Nullwerte
In diesem Thema wird beschrieben, wie der Nullwert in F# verwendet wird.
Nullwerte vor F# 9
Der Nullwert wird in F# normalerweise nicht für Werte oder Variablen verwendet. Null wird jedoch in bestimmten Situationen als abnormer Wert angezeigt. Wenn ein Typ in F# definiert ist, ist NULL nicht als regulärer Wert zulässig, es sei denn, das AllowNullLiteral Attribut wird auf den Typ angewendet. Wenn ein Typ in einer anderen .NET-Sprache definiert ist, ist Null ein möglicher Wert, und wenn Sie mit solchen Typen zusammenarbeiten, kann ihr F#-Code null-Werte aufweisen.
Für einen Typ, der in F# definiert ist und ausschließlich von F# aus verwendet wird, ist die einzige Möglichkeit, einen NULL-Wert direkt mit der F#-Bibliothek zu erstellen, die Verwendung von Unchecked.defaultof oder Array.zeroCreate. Für einen F#-Typ, der von anderen .NET-Sprachen verwendet wird, oder wenn Sie diesen Typ mit einer API verwenden, die nicht in F# geschrieben ist, z. B. .NET Framework, können Nullwerte auftreten.
Sie können den option
Typ in F# verwenden, wenn Sie möglicherweise eine Referenzvariable mit einem möglichen Nullwert in einer anderen .NET-Sprache verwenden. Anstelle von NULL verwenden Sie bei einem F#-option
Typ den Optionswert None
, wenn kein Objekt vorhanden ist. Sie verwenden den Optionswert Some(obj)
mit einem Objekt obj
, wenn ein Objekt vorhanden ist. Weitere Informationen finden Sie unter Optionen. Beachten Sie, dass Sie einen null
-Wert trotzdem in eine Option packen können, wenn es bei Some x
der Fall ist, dass x
null
ist. Aus diesem Grund ist es wichtig, dass Sie None
verwenden, wenn ein Wert null
ist.
Das schlüsselwort null
ist ein gültiges Schlüsselwort in F#, und Sie müssen es verwenden, wenn Sie mit .NET Framework-APIs oder anderen APIs arbeiten, die in einer anderen .NET-Sprache geschrieben sind. Die beiden Situationen, in denen Sie möglicherweise einen NULL-Wert benötigen, sind, wenn Sie eine .NET-API aufrufen und einen Nullwert als Argument übergeben, und wenn Sie den Rückgabewert oder einen Ausgabeparameter aus einem .NET-Methodenaufruf interpretieren.
Um einen NULL-Wert an eine .NET-Methode zu übergeben, verwenden Sie einfach das schlüsselwort null
im aufrufenden Code. Im folgenden Codebeispiel wird dies veranschaulicht.
open System
// Pass a null value to a .NET method.
let ParseDateTime (str: string) =
let (success, res) =
DateTime.TryParse(str, null, System.Globalization.DateTimeStyles.AssumeUniversal)
if success then Some(res) else None
Wenn Sie einen Nullwert interpretieren möchten, der von einer .NET-Methode abgerufen wird, verwenden Sie, wenn möglich, Mustervergleich. Im folgenden Codebeispiel wird gezeigt, wie Sie den Musterabgleich verwenden, um den Nullwert zu interpretieren, der von ReadLine
zurückgegeben wird, wenn versucht wird, über das Ende eines Eingabedatenstroms hinaus zu lesen.
// Open a file and create a stream reader.
let fileStream1 =
try
System.IO.File.OpenRead("TextFile1.txt")
with :? System.IO.FileNotFoundException ->
printfn "Error: TextFile1.txt not found."
exit (1)
let streamReader = new System.IO.StreamReader(fileStream1)
// ProcessNextLine returns false when there is no more input;
// it returns true when there is more input.
let ProcessNextLine nextLine =
match nextLine with
| null -> false
| inputString ->
match ParseDateTime inputString with
| Some(date) -> printfn "%s" (date.ToLocalTime().ToString())
| None -> printfn "Failed to parse the input."
true
// A null value returned from .NET method ReadLine when there is
// no more input.
while ProcessNextLine(streamReader.ReadLine()) do
()
Nullwerte für F#-Typen können auch auf andere Weise generiert werden, z. B. wenn Sie Array.zeroCreate
verwenden, die Unchecked.defaultof
aufruft. Sie müssen mit diesem Code vorsichtig sein, damit die NULL-Werte gekapselt bleiben. In einer Bibliothek, die nur für F# vorgesehen ist, müssen Sie in jeder Funktion nicht auf Nullwerte überprüfen. Wenn Sie eine Bibliothek für die Interoperabilität mit anderen .NET-Sprachen schreiben, müssen Sie möglicherweise Überprüfungen auf NULL-Eingabeparameter hinzufügen und eine ArgumentNullException
auslösen, genau wie in C#- oder Visual Basic-Code.
Sie können den folgenden Code verwenden, um zu überprüfen, ob ein beliebiger Wert null ist.
match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."
Nullwerte beginnend mit F# 9
In F# 9 werden der Sprache zusätzliche Funktionen hinzugefügt, um Mit Verweistypen zu umgehen, die null
als Wert aufweisen können. Diese sind standardmäßig deaktiviert – um sie zu aktivieren, muss die folgende Eigenschaft in Der Projektdatei abgelegt werden:
<Nullable>enable</Nullable>
Dadurch wird das --checknulls+
-Flag an den F#-Compiler übergeben und eine NULLABLE
-Präprozessor-Direktive für den Build-Prozess festgelegt.
Um explizit die Nullierbarkeit zu aktivieren, muss eine Typdeklaration mit der neuen Syntax suffixiert werden:
type | null
Das Balkensymbol |
hat in der Syntax die Bedeutung eines logischen ODERs, das eine Vereinigung von zwei disjunkten Sets von Typen festlegt: den zugrundeliegenden Typ und die löschbare Referenz. Dies ist dasselbe syntaktische Symbol, das zum Deklarieren mehrerer Fälle einer F#-diskriminierten Vereinigung verwendet wird: type AB = A | B
hat entweder die Bedeutung von A
oder B
.
Die nullable Annotation | null
kann an allen Stellen verwendet werden, an denen normalerweise ein Referenztyp verwendet werden würde:
- Felder von Union-Typen, Record-Typen und angepasste Typen.
- Geben Sie Aliase für vorhandene Typen ein.
- Typanwendungen eines generischen Typs.
- Explizite Typ-Annotation, um Bindungen, Parameter oder Rückgabetypen zuzulassen.
- Geben Sie Anmerkungen zu Objektprogrammierungskonstrukten wie Membern, Eigenschaften oder Feldern ein.
type AB = A | B
type AbNull = AB | null
type RecordField = { X: string | null }
type TupleField = string * string | null
type NestedGenerics = { Z : List<List<string | null> | null> | null }
Das Balkensymbol |
hat andere Verwendungen in F#, die zu syntaktischen Mehrdeutigkeiten führen können. In solchen Fällen werden Klammern um den null-annotierten Typ benötigt.
// Unexpected symbol '|' (directly before 'null') in member definition
type DUField = N of string | null
Durch das Umschließen desselben Typs in ein Paar von ( )
Klammern wird das Problem behoben:
type DUField = N of (string | null)
Bei Verwendung im Musterabgleich wird |
verwendet, um verschiedene Musterabgleichsklauseln zu trennen.
match x with
| ?: string | null -> ...
Dieser Codeausschnitt entspricht tatsächlich dem Code, der zuerst einen Typtest mit dem string
Typ durchführt und dann eine separate Klausel für die Behandlung von NULL aufweist:
match x with
| ?: string
| null -> ...
Wichtig
Die zusätzlichen NULL-bezogenen Funktionen wurden der Sprache für die Interoperabilitätszwecke hinzugefügt. Die Verwendung von | null
in der F#-Typmodellierung wird nicht als idiomatisch betrachtet, um fehlende Informationen zu kennzeichnen – verwenden Sie zu diesem Zweck Optionen (wie oben beschrieben). Lesen Sie mehr über Null-bezogene Konventionen im Style Guide.