Udostępnij za pomocą


Wartości null

W tym temacie opisano sposób użycia wartości null w języku F#.

Wartości typu null przed F# 9

Wartość null nie jest zwykle używana w języku F# dla wartości lub zmiennych. Jednak wartość null jest wyświetlana jako nietypowa wartość w niektórych sytuacjach. Jeśli typ jest zdefiniowany w języku F#, wartość null nie jest dozwolona jako wartość regularna, chyba że do typu jest stosowany atrybut AllowNullLiteral AllowNullLiteral. Jeśli typ jest zdefiniowany w innym języku .NET, wartość null jest możliwą wartością, a podczas współdziałania z takimi typami kod F# może napotkać wartości null.

W przypadku typu zdefiniowanego w języku F# i używanego ściśle z języka F#jedynym sposobem utworzenia wartości null przy użyciu biblioteki języka F# jest bezpośrednie użycie polecenia Unchecked.defaultof lub Array.zeroUtwórz. Jednak w przypadku typu F# używanego z innych języków platformy .NET lub jeśli używasz tego typu z interfejsem API, który nie jest napisany w języku F#, na przykład w programie .NET Framework, mogą wystąpić wartości null.

Możesz użyć typu option w języku F#, jeśli możesz użyć zmiennej referencyjnej z możliwą wartością null w innym języku platformy .NET. Zamiast null z typem option w języku F#, należy użyć wartości opcji None, jeśli obiekt nie istnieje. Należy użyć wartości opcji Some(obj) z obiektem obj, jeśli istnieje obiekt. Aby uzyskać więcej informacji, zobacz opcje . Należy pamiętać, że nadal można spakować wartość null do opcji, jeśli dla Some xx okaże się null. Z tego powodu należy użyć None, gdy wartość jest null.

Słowo kluczowe null jest prawidłowym słowem kluczowym w języku F#i należy go używać podczas pracy z interfejsami API programu .NET Framework lub innymi interfejsami API napisanymi w innym języku platformy .NET. Dwie sytuacje, w których może być potrzebna wartość null, to podczas wywoływania interfejsu API platformy .NET i przekazywania wartości null jako argumentu oraz interpretowania wartości zwracanej lub parametru wyjściowego z wywołania metody .NET.

Aby przekazać wartość null do metody .NET, wystarczy użyć słowa kluczowego null w kodzie wywołującym. Poniższy przykład kodu ilustruje to.

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

Aby zinterpretować wartość null uzyskaną z metody .NET, użyj dopasowania wzorca, jeśli to możliwe. W poniższym przykładzie kodu pokazano, jak używać dopasowania do wzorca, aby zinterpretować wartość null zwróconą z ReadLine, gdy próbuje odczytać dane poza końcem strumienia wejściowego.

// 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
    ()

Wartości null dla typów języka F# można również wygenerować na inne sposoby, takie jak użycie Array.zeroCreate, które wywołuje Unchecked.defaultof. Należy być ostrożnym przy użyciu takiego kodu, aby utrzymać wartości null w izolacji. W bibliotece przeznaczonej tylko dla języka F#nie trzeba sprawdzać wartości null w każdej funkcji. Jeśli piszesz bibliotekę do współdziałania z innymi językami platformy .NET, może być konieczne dodanie sprawdzania parametrów wejściowych o wartości null i zgłoszenie ArgumentNullException, podobnie jak w kodzie C# lub Visual Basic.

Możesz użyć następującego kodu, aby sprawdzić, czy dowolna wartość ma wartość null.

match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."

Wartości null rozpoczynające się od języka F# 9

W języku F# 9 dodatkowe możliwości są dodawane do języka w celu obsługi typów odwołań, które mogą mieć null jako wartość. Są one domyślnie wyłączone — aby je włączyć, w pliku projektu należy umieścić następującą właściwość:

<Nullable>enable</Nullable>

Przekazuje to flagę --checknulls+ do kompilatora F# i ustawia dyrektywę preprocesora NULLABLE dla kompilacji.

Aby jawnie wyrazić zgodę na wartość null, należy sufiksować deklarację typu z nową składnią:

type | null

Symbol | ma znaczenie logicznego OR w składni, tworząc unię dwóch rozłącznych zbiorów typów: typu bazowego i odwołania nullable. Jest to ten sam symbol składniowy, który służy do deklarowania wielu przypadków unionów dyskryminacyjnych F#: type AB = A | B oznacza Alub B.

Adnotacja dopuszczająca wartości null | null może być używana we wszystkich miejscach, gdzie zazwyczaj używa się typu referencyjnego:

  • Pola typów unii, typów rekordów i typów niestandardowych.
  • Twórz aliasy dla istniejących typów.
  • Wpisz aplikacje typu ogólnego.
  • Jawne adnotacje typu dla wiązań let, parametrów lub zwracanych typów.
  • Wpisz adnotacje do konstrukcji programowania obiektowego, takich jak członkowie, właściwości lub pola.
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 }

Symbol paska | ma inne zastosowania w języku F#, co może prowadzić do niejednoznaczności składniowych. W takich przypadkach nawiasy są potrzebne wokół typu adnotowanego jako null.

// Unexpected symbol '|' (directly before 'null') in member definition
type DUField = N of string | null

Zawinięcie tego samego typu w parę nawiasów ( ) rozwiązuje problem.

type DUField = N of (string | null)

W przypadku dopasowywania wzorców | służy do oddzielania różnych klauzul dopasowywania wzorców.

match x with
| ?: string | null -> ...

Ten fragment kodu jest w rzeczywistości odpowiednikiem kodu, wykonując najpierw test typu względem typu string, a następnie ma oddzielną klauzulę do obsługi wartości null:

match x with
| ?: string 
| null -> ...

Ważny

Dodatkowe możliwości związane z wartością null zostały dodane do języka dla celów interoperacyjności. Używanie | null w modelowaniu typów języka F# nie jest uważane za idiomatyczne oznaczanie brakujących informacji — w tym celu użyj opcji (zgodnie z powyższym opisem). Przeczytaj więcej na temat konwencji związanych z wartościami null w przewodniku stylu.

Zobacz też