Udostępnij za pośrednictwem


Rekordy (F#)

Rekordy stanowią prosty agregatów nazwanych wartości opcjonalnie z członków.

[ attributes ]
type [accessibility-modifier] typename = { 
    [ mutable ] label1 : type1;
    [ mutable ] label2 : type2;
    ...
    }
    member-list

Uwagi

W poprzednich składni typename jest nazwą typu rekordu, label1 i label2 są nazwy wartości określone jako etykiety, i type1 i type2 typy te wartości.member-listto opcjonalna lista elementów członkowskich typu.

Poniżej przedstawiono kilka przykładów.

type Point = { x : float; y: float; z: float; }
type Customer = { First : string; Last: string; SSN: uint32; AccountNumber : uint32; }

Gdy każda etykieta jest w osobnym wierszu, średnik, jest opcjonalny.

Wartości można ustawić w wyrażeniach, znane jako wyrażeń rekordu.Kompilator ustala typ z etykiety (Jeśli etykiety są wystarczająco różne od tych innych typów rekordów).Nawiasy klamrowe ({}), należy wpisać wyrażenie rekordu.Poniższy kod ilustruje wyrażenie rekord, który inicjuje rekordu z trzech elementów float etykiet x, y i z.

let mypoint = { x = 1.0; y = 1.0; z = -1.0; }

Skrócona forma nie należy używać, jeśli może być innego typu, który także ma takie same etykiety.

type Point = { x : float; y: float; z: float; }
type Point3D = { x: float; y: float; z: float }
// Ambiguity: Point or Point3D? 
let mypoint3D = { x = 1.0; y = 1.0; z = 0.0; }

Etykiety najbardziej niedawno deklarowanego typu pierwszeństwo typu poprzednio zadeklarowanych w poprzednim przykładzie tak mypoint3D jest niezamierzone za Point3D.Można jawnie określić typ rekordu, jak w poniższym kodzie.

let myPoint1 = { Point.x = 1.0; y = 1.0; z = 0.0; }

Metody mogą być definiowane dla typów rekordów tylko dla typu klasy.

Tworzenie rekordów przy użyciu wyrażeń rekordu

Rekordy można zainicjować za pomocą etykiet, które są zdefiniowane w rekordzie.Wyrażenie to jest określone jako wyrażenie rekordu.Użyj nawiasów klamrowych należy wpisać wyrażenie rekordu i używać średnika jako ogranicznika.

Poniższy przykład pokazuje, jak utworzyć rekordu.

type MyRecord = {
    X: int;
    Y: int;
    Z: int 
    }

let myRecord1 = { X = 1; Y = 2; Z = 3; }

Średnikami po ostatniego pola w wyrażeniu rekordu i w definicji typu są opcjonalne, niezależnie od tego, czy pola są w jednym wierszu.

Podczas tworzenia rekordu, należy podać wartości dla każdego pola.Nie można odwołać się do wartości innych pól w wyrażeniu inicjowania dla dowolnego pola.

Poniższy kod typu myRecord2 wywnioskować na podstawie nazwy pól.Opcjonalnie można jawnie określić nazwę typu.

let myRecord2 = { MyRecord.X = 1; MyRecord.Y = 2; MyRecord.Z = 3 }

Inną formę budowy rekordu może być przydatne w trzeba skopiować istniejący rekord i ewentualnie zmieniać niektóre wartości pola.Poniższy wiersz kodu ilustruje to.

let myRecord3 = { myRecord2 with Y = 100; Z = 2 }

Ta forma wyrażenia rekord jest nazywana kopiowania i zaktualizować rekord wyrażenie.

Rekordy są niezmienne domyślnie; można jednak łatwo utworzyć zmodyfikowanych rekordów za pomocą wyrażenia kopii i aktualizacji.Można także jawnie określić tych pól.

type Car = {
    Make : string
    Model : string
    mutable Odometer : int
    }
let myCar = { Make = "Fabrikam"; Model = "Coupe"; Odometer = 108112 }
myCar.Odometer <- myCar.Odometer + 21

Nie używaj atrybutu DefaultValue z pól rekordu.Lepszym rozwiązaniem jest zdefiniowanie domyślnego wystąpienia rekordów z polami zawierającymi wartości domyślne, a następnie używać kopii i zaktualizować rekord wyrażenie ustawić żadnych pól, które różnią się od wartości domyślne.

// Rather than use [<DefaultValue>], define a default record.
type MyRecord =
    { 
        field1 : int 
        field2 : int
    }

let defaultRecord1 = { field1 = 0; field2 = 0 }
let defaultRecord2 = { field1 = 1; field2 = 25 }

// Use the with keyword to populate only a few chosen fields
// and leave the rest with default values.
let rr3 = { defaultRecord1 with field2 = 42 }

Wzorzec dopasowania z rekordami

Rekordy można się z dopasowywania do wzorca.Można jawnie określić niektóre pola i są dostępne zmienne dla innych pól, które zostanie przypisany podczas pasują.Poniższy przykład kodu ilustruje to.

type Point3D = { x: float; y: float; z: float }
let evaluatePoint (point: Point3D) =
    match point with
    | { x = 0.0; y = 0.0; z = 0.0 } -> printfn "Point is at the origin."
    | { x = xVal; y = 0.0; z = 0.0 } -> printfn "Point is on the x-axis. Value is %f." xVal
    | { x = 0.0; y = yVal; z = 0.0 } -> printfn "Point is on the y-axis. Value is %f." yVal
    | { x = 0.0; y = 0.0; z = zVal } -> printfn "Point is on the z-axis. Value is %f." zVal
    | { x = xVal; y = yVal; z = zVal } -> printfn "Point is at (%f, %f, %f)." xVal yVal zVal

evaluatePoint { x = 0.0; y = 0.0; z = 0.0 }
evaluatePoint { x = 100.0; y = 0.0; z = 0.0 }
evaluatePoint { x = 10.0; y = 0.0; z = -1.0 }

Dane wyjściowe ten kod wygląda następująco:

Point is at the origin.
Point is on the x-axis. Value is 100.000000.
Point is at (10.000000, 0.000000, -1.000000).

Różnice między rekordami i klasy

Pola rekordu różnią się od klas, że są one narażone automatycznie jako właściwości i są one używane do tworzenia i kopiowanie rekordów.Budowa rekordu również różni się od klasy budowy.W polu Typ rekordu nie można zdefiniować konstruktora.Zamiast tego stosuje się składni budowy, opisane w tym temacie.Klas nie ma bezpośredniego związku między parametry konstruktora, pola i właściwości.

Typy Unii i struktury, takie jak rekordy mają semantykę strukturalnych równości.Klasy mają odniesienie semantykę równości.Poniższy przykład kodu pokazuje to.

type RecordTest = { X: int; Y: int }
let record1 = { X = 1; Y = 2 }
let record2 = { X = 1; Y = 2 }
if (record1 = record2) then
    printfn "The records are equal." 
else
    printfn "The records are unequal."

Jeśli piszesz sam kod z klas obiektów klasy dwóch będzie nierówne, ponieważ dwie wartości stanowiłaby dwóch obiektów na stercie i mogłoby być porównywane tylko adresy (chyba że zastępuje typu klasy System.Object.Equals metody).

Zobacz też

Informacje

Klasy (F#)

Dopasowanie wzorca (F#)

Inne zasoby

Typy F#

Materiały referencyjne dotyczące języka F#