Null-värden
Det här avsnittet beskriver hur null-värdet används i F#.
Null-värde
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.zeroCreate. 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
typen 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, för Some x
, x
rå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. Följande kodexempel visar 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."