Megosztás a következőn keresztül:


Null értékek

Ez a témakör a null érték F#-ban való használatát ismerteti.

Null értékek az F# 9 előtt

A null értéket az F# általában nem használja értékekhez vagy változókhoz. A null érték azonban bizonyos helyzetekben rendellenes értékként jelenik meg. Ha egy típus az F#-ban van definiálva, a null érték csak akkor engedélyezett normál értékként, ha az AllowNullLiteral attribútumot alkalmazza a típusra. Ha egy típus más .NET-nyelven van definiálva, a null egy lehetséges érték, és ha ilyen típusokkal működik együtt, az F#-kód null értékekkel találkozhat.

Az F#-ban definiált és szigorúan az F#-ból használt típus esetében az egyetlen módja annak, hogy közvetlenül az F# kódtár használatával null értéket hozzon létre, ha Nem bejelölt.defaultof vagy Array.zeroCreate. Más .NET-nyelvekből használt F#-típus esetén azonban, vagy ha ezt a típust nem F# nyelven írt API-val használja, például a .NET-keretrendszerben, null értékek is előfordulhatnak.

Az F#-ben a option típust akkor használhatja, amikor egy referenciaváltozót esetleg null értékkel használná egy másik .NET nyelven. Null érték helyett F# option típusnál az opciós értéket None használjuk, ha nincs elérhető objektum. Objektum esetén Some(obj)obj beállításértéket kell használnia. További információ: Beállítások. Vegye figyelembe, hogy null értéket akkor is becsomagolhat egy opcióba, ha Some xesetén xnull. Emiatt fontos, hogy a None-t használja, amikor egy érték null.

A null kulcsszó érvényes kulcsszó az F#-ban, és akkor kell használnia, ha .NET-keretrendszer API-kkal vagy más .NET nyelven írt API-kkal dolgozik. Az a két helyzet, amikor null értékre lehet szüksége, amikor meghív egy .NET API-t, és argumentumként egy null értéket ad át, és amikor a visszatérési értéket vagy a kimeneti paramétert egy .NET-metódushívásból értelmezi.

Ha null értéket szeretne átadni egy .NET-metódusnak, használja a null kulcsszót a hívókódban. Az alábbi példakód ezt szemlélteti.

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

A .NET-metódusból kapott null érték értelmezéséhez használja a mintaegyezést, ha tudja. Az alábbi példakód bemutatja, hogyan használható mintaegyeztetés a ReadLine által visszaadott null érték értelmezésére, amikor egy bemeneti adatfolyam végén próbál olvasni.

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

Az F#-típusok null értékei más módon is létrehozhatók, például Array.zeroCreatehasználatakor, amely meghívja Unchecked.defaultof. Az ilyen kóddal óvatosan kell bánni, hogy a null értékeket lezárva tartsa. A csak F#-nak szánt kódtárakban nem kell null értékeket keresnie minden függvényben. Ha más .NET-nyelvekkel való együttműködéshez kódtárat ír, előfordulhat, hogy null bemeneti paramétereket kell ellenőriznie, és ArgumentNullExceptionkell dobnia, ahogyan a C# vagy a Visual Basic kódban is.

Az alábbi kóddal ellenőrizheti, hogy egy tetszőleges érték null-e.

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

Null értékek az F# 9-től kezdve

Az F# 9-ben további képességeket adnak hozzá a nyelvhez a referenciatípusok kezeléséhez, amelyek null lehetnek értékként. Ezek alapértelmezés szerint ki vannak kapcsolva – a bekapcsolásukhoz a következő tulajdonságot kell elhelyezni a projektfájlban:

<Nullable>enable</Nullable>

Ez átadja a --checknulls+jelzőt az F# fordítónak, és beállít egy NULLABLEelőprocesszor-irányelv a buildhez.

Ahhoz, hogy explicit módon engedélyezhesse a nullérték megengedését, a típusdeklarációt az új szintaxis utótagjaként kell megadni.

type | null

A sávszimbólum | a szintaxisban egy logikai VAGY jelentéssel rendelkezik, amely két különálló halmazból álló egyesítést hoz létre: az alapul szolgáló típust és a null értékű hivatkozást. Ez ugyanaz a szintaktikai szimbólum, amelyet az F#-diszkriminált unió több esetének deklarálásához használnak: type AB = A | B vagy A, vagy Bjelentését hordozza.

A nullázható annotáció | null minden olyan helyen használható, ahol általában referencia típust használnak.

  • Egyesítő típusok, rekordtípusok és egyéni típusok mezői.
  • Írja be az aliasokat a meglévő típusokba.
  • Írja be az általános típusú alkalmazásokat.
  • Explicit típusú széljegyzetek, amelyek lehetővé teszik a kötéseket, paramétereket vagy visszatérési típusokat.
  • Írjon be széljegyzeteket az objektumprogramozási szerkezetekhez, például tagokhoz, tulajdonságokhoz vagy mezőkhöz.
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 }

A sávszimbólum | egyéb használati adatokkal rendelkezik az F#-ban, ami szintaktikai kétértelműséghez vezethet. Ilyen esetekben zárójelekre van szükség a null jegyzetekkel ellátott típus körül:

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

Ha ugyanazt a típust egy pár ( ) zárójelbe csomagolja, az megoldja a problémát:

type DUField = N of (string | null)

A mintaegyeztetés során a | különböző mintaegyeztetési záradékok elválasztására szolgál.

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

Ez a kódrészlet valójában egyenértékű azzal, hogy a kód először típustesztet végez a string típuson, majd külön záradékkal rendelkezik a null érték kezeléséhez:

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

Fontos

Az interoperabilitás érdekében további, nulla értéket támogató képességek kerültek hozzáadásra a nyelvhez. A | null F#-típusmodellezésben való használata nem tekinthető idiomatikusnak a hiányzó adatok jelöléséhez – ehhez használja a lehetőségeket (a fent leírtak szerint). A stíluskalauzban tudjon meg többet a null értékekkel kapcsolatos konvenciókról.

Lásd még: