Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ha különböző modelltípusok egyesítése nélkül szeretne mezőket megosztani, használjon rekordpárokat, amelyek az F# 11-től érhetők el.
Meződeklarációk ...Type új névvel ellátott rekordhoz való hozzáadására vagy ...expression mezőértékek hozzáadására egy névvel ellátott vagy névtelen rekordhoz. A deklaráció újrafelhasználása és az értékleképezés független választás.
Rekordtípusok írása
A kapcsolatmezők konfigurációtípusok közötti megosztásához terjesszen át Endpoint egy új rekorddeklarációra:
type Endpoint = { Host: string; Port: int }
type ClientOptions =
{ ...Endpoint
TimeoutSeconds: int }
ClientOptions van Host, Portés TimeoutSeconds. Ez egy különálló névleges típus, nem altípus Endpoint .
Több forrás és explicit deklaráció is megjelenhet ugyanabban a típusdefinícióban:
type Logging = { LogLevel: string }
type LoggedClientOptions = { ...ClientOptions; ...Logging }
Csak a rekordmezők vesznek részt. A metódusok, a nem rekordmezők és a statikus tagok nem másolódnak. A forrás lehet névvel ellátott rekord vagy névtelen rekordtípus, beleértve egy névtelen rekord rövidítését is. A típuspár célhelyének nevesített rekordtípusnak kell lennie.
Rekordértékek írása
Másolja a végpontot az ügyfélbeállításokba, majd használjon névtelen rekordot a gazdagép lecseréléséhez:
let local = { Host = "localhost"; Port = 5432 }
let options: ClientOptions = { ...local; TimeoutSeconds = 30 }
let remote = {| ...options; Host = "db.example.com" |}
printn $"{remote.Host}:{remote.Port}, timeout {remote.TimeoutSeconds}s"
// db.example.com:5432, timeout 30s
A kifejezéspárok névvel ellátott vagy névtelen rekordforrásokat és célhelyeket fogadnak el, beleértve a strukturált rekordokat is. Minden célmezőnek értéket kell kapnia. Egy explicit céljegyzet akkor hasznos, ha több elnevezett rekordtípus megosztja a címkéket.
Mező típusának megerősítése
Egy későbbi meződeklaráció lecserélheti az oldalpármező típusát. Jelöljön például egy elemezett azonosítót a következővel type CustomerId = CustomerId of System.Guid, majd különböztetje meg az importált rekordot az azonosítóval:
type ImportedCustomer = { Name: string; Id: string }
type IdentifiedCustomer = { ...ImportedCustomer; Id: CustomerId }
let identify (source: ImportedCustomer) =
match Guid.TryParse source.Id with
| true, id -> Ok ({ ...source; Id = CustomerId id }: IdentifiedCustomer)
| false, _ -> Error "Invalid customer identifier."
Guid.TryParse ellenőrzi a szöveget; az oldalpár csak a másolt mezőket másolja.
CustomerId anélkül különbözteti meg az azonosítókat a többi grafikus felhasználói felülettől, hogy további szabályokat ír elő.
Független modellek egyesítése
Deklarációk összeállítása válogatott névleges rekordból és névtelen rekordtípusból, majd értékek összeállítása független forrásokból:
type PublicProductFields = { Name: string; UnitPrice: decimal }
type ProductRow = { ...PublicProductFields; InternalCost: decimal }
type StockCounts = {| InStock: int; Reserved: int |}
type ProductCard =
{ ...PublicProductFields
...StockCounts
CanOrder: bool }
let product: ProductRow =
{ Name = "Notebook"; UnitPrice = 12.50m; InternalCost = 4m }
let stock: StockCounts = {| InStock = 8; Reserved = 2 |}
let card: ProductCard =
{ ...product; ...stock; CanOrder = stock.InStock > stock.Reserved }
let viewState = {| ...card; Selected = false |}
let selected = {| ...viewState; Selected = true |}
A névvel ellátott és névtelen források adják meg az adatokat ProductCard; a kártya ezután névtelen megtekintési állapotot biztosít.
CanOrder egyszer lesz kiszámítva, és nem számítja újra újra, amikor egy későbbi konstrukció módosítja a darabszámokat.
Project egy ismert célba
A céltípus kijelöli a megtartandó mezőket. Több forrás is elláthat cserét:
let endpoint: Endpoint = { ...options }
let overrides = {| Host = "db.example.com"; Port = 5433 |}
let production: ClientOptions =
{ ...options; ...overrides; TimeoutSeconds = 60 }
printn $"{endpoint.Host}:{endpoint.Port}"
printn $"{production.Host}:{production.Port}, timeout {production.TimeoutSeconds}s"
// localhost:5432
// db.example.com:5433, timeout 60s
endpoint csak Host és Port; production egyesíti a forrásokat és a explicit felülbírálásokat. A céltól hiányzó explicit mezők továbbra is hibák maradnak.
Egy névtelen rekord az összes közreműködő mezőt felveszi. A megnevezett célnak következtethetőnek kell lennie. Az ismeretlen forrásoknak saját széljegyzetekre van szükségük, például (source: ClientOptions) egy függvényparaméteren.
Mezőrend és felülbírálások
A hozzájárulások balról jobbra olvashatók. Ismétlődő mezőnév esetén a jobb szélső hozzájárulás nyer. A szabály a típusok meződeklarációira és a kifejezések mezőértékére egyaránt vonatkozik.
let laterHost = {| Host = "db.example.com" |}
let corrected: Endpoint = { ...local; ...laterHost; Port = 5433 }
A típus felülbírálása után adja meg a cseretípus értékét. Az ismétlődő explicit mezők, például { Host = "first"; Host = "second" }a hibák továbbra is megmaradnak.
Típusdeklarációk esetén egy nyertes mező jelenik meg a nyertes hozzájárulás helyén. A forrás mezői megőrzik a forrásrendjüket. Ez a sorrend a konstruktorok és az aláírások megfelelőségét érinti.
Kiértékelés és másolás
Az oldalpáros forráskifejezések egyenként, forrás sorrendben futnak, még akkor is, ha egy későbbi hozzájárulás lecseréli az általuk megadott összes mezőt:
let visits = ResizeArray<string>()
let hostFrom source host =
visits.Add source
{| Host = host |}
let selected =
{| ...hostFrom "first" "localhost"
...hostFrom "second" "db.example.com" |}
assert (selected.Host = "db.example.com")
assert (Seq.toList visits = [ "first"; "second" ])
Az oldalpárok egy új rekordot hoznak létre sekély mezőpéldányokkal és az explicit hozzárendelésekkel megegyező átalakításokkal. A mezők által hivatkozott mutable objektumok továbbra is megosztottak maradnak.
A beágyazott mezőfrissítések ugyanúgy működnek az oldalpárokkal, mint a másolással és frissítéssel:
let original = {| Connection = local; Retries = 3 |}
let changed = {| ...original; Connection.Port = 5433 |}
assert (changed.Connection.Port = 5433)
assert (original.Connection.Port = 5432)
Egy későbbi hozzájárulás a Connection mező korábbi beágyazott frissítésének lecseréléséhez. Helyezzen szándékos felülbírálásokat a felülbírálandó oldalpárok után.
Figyelmeztetések árnyékolt mezőkkel kapcsolatban
Egy későbbi oldalpár véletlenül visszavonhat egy explicit választást. A fordító alapértelmezés szerint a következő figyelmeztetéseket jelenti:
| Warning | Meaning |
|---|---|
| FS3897 | A típuspárok mezői egy korábbi explicit meződeklarációt árnyékként használnak. |
| FS3898 | Egy kifejezésből származó mező árnyékolással egy korábbi explicit mezőkötést eredményez. |
Például a következőt veszi fel Hostlocal, { Host = "db.example.com"; ...local } nem "db.example.com".
Egyéb átfedések naplózásához engedélyezze az alábbi opt-in figyelmeztetéseket:
| Warning | Meaning |
|---|---|
| FS3905 | A típuspárok árnyékolással árnyékot ad egy mezőnek egy korábbi típuspárból. |
| FS3906 | Egy explicit mező árnyékolást ad egy korábbi oldalpár mezőinek. |
| FS3907 | Egy kifejezés egy korábbi kifejezéspár mezőinek árnyékolását jelzi. |
<WarnOn>$(WarnOn);3905;3906;3907</WarnOn>
Ezek az értesítések nem változtatják meg a jobb oldali nyerési viselkedést.
Reprezentáció és API-kompatibilitás
A típuspárok másolási mező nem módosíthatók és mezőszintű attribútumok. Nem másolnak típusszintű attribútumokat; a cél saját [<Struct>] attribútuma határozza meg a reprezentációját. A forrástípus argumentumainak meg kell felelniük a forrás általános korlátozásainak, beleértve a mértékegység-megkötéseket is.
Important
Típuspárokat csak akkor használjon, ha a közös evolúció szándékos. A forrásmező módosítása módosíthatja a cél nyilvános mezőit, konstruktorát, attribútumait vagy kényszereit anélkül, hogy az adott célhelyet szerkesztené.
Az oldalpárok nem kerülik meg az akadálymentességi ellenőrzéseket. A null értékű rekordok érvénytelen szórási források; annak használata előtt állapítsa meg, hogy a null értékű értékek nem null értékűek. A rendszer elutasítja a ciklikus függőségeket a spreadeken keresztül . A hagyományos rekurzív rekordmezők nem tilthatók csak azért, mert a deklaráció spreadet is használ.
Típuspárok a fájlokban .fsi működnek. Az aláírások explicit mezőket használhatnak, miközben a megvalósítás oldalpárokat vagy fordítottakat használ, feltéve, hogy az eredményül kapott mezők és azok sorrendje megegyezik. Az idézőjelek a kidolgozott rekordszerkezetet tartalmazzák, nem az oldalpárcsomópontot.
Oldalpárok vagy másolás és frissítés kiválasztása
Egy forrásból származó azonos típusú frissítéshez használjon másolási és frissítési kifejezéseket . Oldalpárok használatával egyesítheti a forrásokat, más rekordtípusra vetítheti a projektet, vagy újra felhasználhatja a meződeklarációkat. Ne egyesítse with és ... ne használja ugyanabban a rekordkifejezésben.
Az oldalpárok nem vonatkoznak gyűjteményekre, objektumkifejezésekre, tetszőleges .NET objektumokra vagy C# rekordokra. Nem adnak meg rekordmintaszintaxist. A rekordkonstruktorok egy különálló F# 11.2-funkció.