Sdílet prostřednictvím


Hodnoty null

Toto téma popisuje, jak se v jazyce F# používá hodnota null.

Hodnoty null před F# 9

Hodnota null se obvykle nepoužívá v jazyce F# pro hodnoty nebo proměnné. Hodnota null se však v určitých situacích zobrazuje jako neobvyklá hodnota. Pokud je typ definován v jazyce F#, hodnota null není povolena jako běžná hodnota, pokud je použit atribut AllowNullLiteral na typ. Pokud je typ definován v jiném jazyce .NET, hodnota null je možná hodnota a při spolupráci s těmito typy může kód F# narazit na hodnoty null.

Pro typ definovaný v jazyce F# a použitý výhradně z jazyka F# je jediným způsobem, jak přímo pomocí knihovny jazyka F# vytvořit hodnotu null, použití Unchecked.defaultof nebo Array.zeroCreate. Pokud se typ F# používá z jiných programovacích jazyků v rámci .NET, nebo pokud tento typ použijete s API, které není napsané v jazyce F#, jako je například .NET Framework, mohou se vyskytnout hodnoty null.

Typ option v jazyce F# můžete použít, když můžete použít referenční proměnnou s možnou hodnotou null v jiném jazyce .NET. Místo hodnoty null s typem option jazyka F# použijete hodnotu možnosti None, pokud neexistuje žádný objekt. Mohli byste použít hodnotu možnosti Some(obj) s objektem obj, pokud existuje nějaký objekt. Další informace naleznete v tématu Možnosti. Všimněte si, že stále můžete zabalit hodnotu null do Option, pokud x bude nullv případě Some x. Z tohoto důvodu je důležité použít None, pokud je hodnota null.

Klíčové slovo null je platné klíčové slovo v jazyce F# a musíte ho použít při práci s rozhraními API rozhraní .NET Framework nebo jinými rozhraními API napsanými v jiném jazyce .NET. Dvě situace, kdy můžete potřebovat hodnotu null, jsou při volání rozhraní .NET API a předání hodnoty null jako argumentu a při interpretaci návratové hodnoty nebo výstupního parametru z volání metody .NET.

Pokud chcete metodě .NET předat hodnotu null, stačí použít klíčové slovo null ve volajícím kódu. Následující příklad kódu to ilustruje.

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

Chcete-li interpretovat hodnotu null získanou z metody .NET, použijte porovnávání vzorů, pokud je to možné. Následující příklad kódu ukazuje, jak pomocí porovnávání vzorů interpretovat hodnotu null vrácenou z ReadLine při pokusu o přečtení za konec vstupního datového proudu.

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

Hodnoty null pro typy jazyka F# lze také vygenerovat jinými způsoby, například při použití Array.zeroCreate, která volá Unchecked.defaultof. U takového kódu musíte být opatrní, abyste udrželi hodnoty null zapouzdřené. V knihovně určené pouze pro jazyk F# nemusíte kontrolovat hodnoty null v každé funkci. Pokud píšete knihovnu pro spolupráci s jinými jazyky .NET, možná budete muset přidat kontroly vstupních parametrů s hodnotou null a vyvolat ArgumentNullException, stejně jako v kódu jazyka C# nebo Visual Basic.

Pomocí následujícího kódu můžete zkontrolovat, jestli je libovolná hodnota null.

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

Hodnoty null začínající F# 9

V jazyce F# 9 se do jazyka přidávají další funkce, které se můžou zabývat odkazovými typy, které můžou mít null jako hodnotu. Ty jsou ve výchozím nastavení vypnuté – pokud je chcete zapnout, musí být do souboru projektu vložena následující vlastnost:

<Nullable>enable</Nullable>

To předá --checknulls+příznak kompilátoru F# a nastaví NULLABLEpokyn preprocesoru pro sestavení.

Aby bylo možné explicitně zapnout nulovatelnost, musí být deklarace typu opatřena novou syntaxí:

type | null

Symbol pruhu | má význam logické or v syntaxi, sestavení sjednocení dvou nesouvislé sady typů: základní typ a odkaz s možnou hodnotou null. Jedná se o stejný syntaktický symbol, který se používá k deklaraci více případů diskriminovaného svazu v jazyce F#: type AB = A | B nese význam buď A, nebo B.

Anotace s nulovou hodnotou | null lze použít na všech místech, kde se obvykle používá referenční typ.

  • Pole sjednocených typů, záznamových typů a vlastních typů
  • Zadejte aliasy pro existující typy.
  • Zadejte aplikace obecného typu.
  • Explicitní poznámky k typům, které umožňují vazby, parametry nebo návratové typy.
  • Zadejte poznámky k konstruktorům objektového programování, jako jsou členy, vlastnosti nebo pole.
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 pruhu | má v jazyce F# jiné použití, což může vést k syntaktické nejednoznačnosti. V těchto případech jsou potřebné závorky kolem typu s nulovou anotací.

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

Zabalení stejného typu do dvojice ( ) závorek problém vyřeší:

type DUField = N of (string | null)

Při použití při porovnávání vzorů se | používá k oddělení různých klauzulí porovnávání vzorů.

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

Tento fragment kódu je ve skutečnosti ekvivalentní kódu, který nejprve provádí test typu string a pak má samostatnou klauzuli pro zpracování hodnoty null:

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

Důležitý

Další možnosti související s hodnotou null byly přidány do jazyka pro účely interoperability. Použití | null v modelování typů jazyka F# se nepovažuje za idiomatické pro označení chybějících informací – pro tento účel použijte možnosti typu option (jak je popsáno výše). Přečtěte si další informace o konvencích souvisejících s hodnotou null v průvodci stylem.

Viz také