Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här avsnittet beskriver hur null-värdet används i F#.
Null-värden före F# 9
Null-värdet används normalt inte i F# för värden eller variabler. Null visas dock som ett onormalt värde i vissa situationer. Om en typ definieras i F#tillåts inte null som ett vanligt värde om inte attributet AllowNullLiteral tillämpas på typen. Om en typ definieras på något annat .NET-språk är null ett möjligt värde, och när du samverkar med sådana typer kan F#-koden stöta på null-värden.
För en typ som definierats i F# och används strikt från F#, är det enda sättet att skapa ett null-värde med hjälp av F#-biblioteket direkt att använda Unchecked.defaultof eller Array.zeroSkapa. Men för en F#-typ som används från andra .NET-språk, eller om du använder den typen med ett API som inte är skrivet i F#, till exempel .NET Framework, kan null-värden inträffa.
Du kan använda option typ i F# när du kan använda en referensvariabel med ett möjligt null-värde på ett annat .NET-språk. I stället för null, med en F#-option typ, använder du alternativvärdet None om det inte finns något objekt. Du använder alternativvärdet Some(obj) med ett objekt obj när det finns ett objekt. Mer information finns i Alternativ. Observera att du fortfarande kan packa ett null värde i ett Alternativ om Some x för xråkar vara null. Därför är det viktigt att du använder None när ett värde är null.
Nyckelordet null är ett giltigt nyckelord i F#, och du måste använda det när du arbetar med .NET Framework-API:er eller andra API:er som är skrivna på ett annat .NET-språk. De två situationer där du kan behöva ett null-värde är när du anropar ett .NET-API och skickar ett null-värde som ett argument, och när du tolkar returvärdet eller en utdataparameter från ett .NET-metodanrop.
Om du vill skicka ett null-värde till en .NET-metod använder du bara nyckelordet null i den anropande koden. Följande kodexempel illustrerar detta.
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
Om du vill tolka ett null-värde som hämtas från en .NET-metod använder du mönstermatchning om du kan. I följande kodexempel visas hur du använder mönstermatchning för att tolka null-värdet som returneras från ReadLine när det försöker läsa förbi slutet av en indataström.
// 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
()
Null-värden för F#-typer kan också genereras på andra sätt, till exempel när du använder Array.zeroCreate, som anropar Unchecked.defaultof. Du måste vara försiktig med sådan kod för att behålla null-värdena inkapslade. I ett bibliotek som endast är avsett för F# behöver du inte söka efter null-värden i varje funktion. Om du skriver ett bibliotek för interoperation med andra .NET-språk kan du behöva lägga till kontroller för null-indataparametrar och utlösa en ArgumentNullException, precis som du gör i C# eller Visual Basic-kod.
Du kan använda följande kod för att kontrollera om ett godtyckligt värde är null.
match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."
Null-värden som börjar med F# 9
I F# 9 läggs extra funktioner till i språket för att hantera referenstyper som kan ha null som ett värde. De är inaktiverade som standard – för att aktivera dem måste följande egenskap placeras i projektfilen:
<Nullable>enable</Nullable>
Detta skickar --checknulls+-flaggan till F#-kompilatorn och anger ett NULLABLEförprocessordirektiv för byggprocessen.
Om du uttryckligen ska kunna välja null måste en typdeklaration vara suffixad med den nya syntaxen:
type | null
Stapelsymbolen | har innebörden av en logisk ELLER i syntaxen och skapar en union med två olika typer: den underliggande typen och den nullbara referensen. Detta är samma syntaktiska symbol som används för att deklarera flera fall av en F#-diskriminerad union: type AB = A | B bär innebörden av antingen Aeller B.
Den nullbara anteckningen | null kan användas på alla platser där en referenstyp normalt används:
- Fält för unionstyper, rekordtyper och anpassade typer.
- Skriv alias till befintliga typer.
- Skriv program av allmän typ.
- Explicita typanteckningar för att tillåta bindningar, parametrar eller returtyper.
- Skriv anteckningar till objektprogrammeringskonstruktioner som medlemmar, egenskaper eller fält.
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 }
Stapelsymbolen | har andra användningar i F# som kan leda till syntaktiska tvetydigheter. I sådana fall behövs parenteser runt den null-annoterade typen.
// Unexpected symbol '|' (directly before 'null') in member definition
type DUField = N of string | null
Om du omsluter samma typ i ett par ( ) parenteser åtgärdas problemet:
type DUField = N of (string | null)
När | används i mönstermatchning, används det för att separera olika villkor.
match x with
| ?: string | null -> ...
Det här kodfragmentet motsvarar faktiskt kod som först utför ett typtest mot den string typen och sedan har en separat sats för hantering av null:
match x with
| ?: string
| null -> ...
Viktig
De extra null-relaterade funktionerna har lagts till i språket i samverkanssyfte. Att använda | null i F#-typmodellering anses inte vara idiomatiskt för att beteckna information som saknas – för det ändamålet använder du alternativ (enligt beskrivningen ovan). Läs mer om null-relaterade konventioner i formatguiden.