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


Aláírások

Az aláírási fájlok információkat tartalmaznak az F#-programelemek egy készletének nyilvános aláírásairól, például típusokról, névterekről és modulokról. A programelemek akadálymentességének megadására használható.

Megjegyzések

Minden F#-kódfájlhoz rendelkezhet aláírásfájllal, amely a kódfájl nevével megegyező nevű, de .fs helyett .fsi kiterjesztésű fájl. Ha közvetlenül a parancssort használja, aláírásfájlokat is hozzáadhat a fordítási parancssorhoz. A kódfájlok és az aláírási fájlok megkülönböztetése érdekében a kódfájlokat implementációs fájloknak is nevezik. Egy projektben az aláírási fájlnak meg kell előznie a társított kódfájlt.

Az aláírási fájl a megfelelő implementációs fájlban található névtereket, modulokat, típusokat és tagokat ismerteti. Az aláírási fájlban található információk segítségével megadhatja, hogy a megfelelő implementációs fájlban lévő kód mely részei érhetők el a implementálási fájlon kívüli kódból, és hogy mely részek tartoznak a implementációs fájlba. Az aláírásfájlban szereplő névtereknek, moduloknak és típusoknak a implementálási fájlban szereplő névterek, modulok és típusok részhalmazának kell lenniük. A jelen témakör későbbi részében feljegyzett kivételek miatt az aláírási fájlban nem szereplő nyelvi elemek privátnak minősülnek a megvalósítási fájlban. Ha nem található aláírásfájl a projektben vagy a parancssorban, a rendszer az alapértelmezett akadálymentességet használja.

Az alapértelmezett akadálymentességgel kapcsolatos további információkért lásd : Hozzáférés-vezérlés.

Az aláírási fájlban nem ismételje meg az egyes metódusok vagy függvények típusainak és implementációinak definícióját. Ehelyett minden metódushoz és függvényhez használja az aláírást, amely a modul vagy névtértöredék által implementált funkciók teljes specifikációjaként működik. A típus-aláírás szintaxisa megegyezik az absztrakciós metódus deklarációiban az interfészekben és az absztrakt osztályokban használt szintaxissal, és az IntelliSense és az F#-értelmező is fsi.exe, amikor megfelelően lefordított bemenetet jelenít meg.

Ha nincs elegendő információ a típus-aláírásban annak jelzéséhez, hogy egy típus lezárva van-e, vagy interfésztípusról van-e szó, hozzá kell adnia egy attribútumot, amely a típus természetét jelzi a fordítóban. Az ehhez a célra használt attribútumokat az alábbi táblázat ismerteti.

Attribútum Leírás
[<Sealed>] Olyan típus esetén, amely nem rendelkezik absztrakt taggal, vagy amelyet nem szabad kiterjeszteni.
[<Interface>] Interfésznek számító típus esetén.

A fordító hibát okoz, ha az attribútumok nem összhangban vannak az aláírás és a végrehajtási fájlban lévő deklaráció között.

A kulcsszóval val aláírást hozhat létre egy értékhez vagy függvényértékhez. A kulcsszó type egy típus-aláírást vezet be.

A fordítóval aláírásfájlt --sig hozhat létre. Általában nem ír manuálisan .fsi fájlokat. Ehelyett .fsi fájlokat hozhat létre a fordító használatával, hozzáadhatja őket a projekthez, ha van ilyen, és szerkesztheti őket olyan metódusok és függvények eltávolításával, amelyeket nem szeretne elérni.

A típusaadékokra több szabály is létezik:

  • A implementációs fájlban szereplő rövidítések nem egyeznek meg egy aláírásfájlban lévő rövidítés nélküli típussal.

  • A rekordoknak és a diszkriminált egyesítőknek vagy az összes mezőt és konstruktort közzé kell tennie, és az aláírásban szereplő sorrendnek meg kell egyeznie a végrehajtási fájlban szereplő sorrenddel. Az osztályok az aláírásban lévő mezők és metódusok némelyikét, egészét vagy egyikét sem fedhetik fel.

  • A konstruktorokkal rendelkező osztályoknak és struktúráknak közzé kell tennie az alaposztályaik deklarációit (a deklarációt inherits ). Emellett a konstruktorokkal rendelkező osztályoknak és struktúráknak el kell fedniük az összes absztrakt metódusukat és felületi deklarációjukat.

  • A felülettípusoknak meg kell fedniük az összes metódusukat és interfészüket.

Az érték-aláírásokra vonatkozó szabályok a következők:

  • Az akadálymentesség módosítóinak (publicinternalstb.) és az inline aláírásban szereplő módosítóknak mutable meg kell egyeznie a megvalósításban lévőkkel.

  • Az általános típusparaméterek számának (implicit módon kikövetkeztetett vagy explicit módon deklarált) egyeznie kell, az általános típusparaméterek típus- és típuskorlátozásainak pedig egyeznie kell.

  • Ha az Literal attribútumot használja, az aláírásban és az implementációban is meg kell jelennie, és mindkettőhöz ugyanazt a literális értéket kell használni.

  • Az aláírások és implementációk paramétereinek (más néven arity) mintájának konzisztensnek kell lennie.

  • Ha egy aláírásfájl paraméternevei eltérnek a megfelelő implementációs fájltól, a rendszer ehelyett az aláírási fájlban lévő nevet használja, ami hibakeresés vagy profilkészítés esetén problémákat okozhat. Ha értesítést szeretne kapni az ilyen eltérésekről, engedélyezze a 3218-at a projektfájlban vagy a fordító meghívásakor (lásd --warnon a Fordító beállításai területen).

Az alábbi példakód egy olyan aláírásfájlra mutat be példát, amely névtérrel, modullal, függvényértékkel és a megfelelő attribútumokkal együtt írja be az aláírásokat. A megfelelő implementációs fájlt is megjeleníti.

// Module1.fsi

namespace Library1
  module Module1 =
    val function1 : int -> int
    type Type1 =
        new : unit -> Type1
        member method1 : unit -> unit
        member method2 : unit -> unit

    [<Sealed>]
    type Type2 =
        new : unit -> Type2
        member method1 : unit -> unit
        member method2 : unit -> unit

    [<Interface>]
    type InterfaceType1 =
        abstract member method1 : int -> int
        abstract member method2 : string -> unit

Az alábbi kód a megvalósítási fájlt mutatja.

namespace Library1

module Module1 =

    let function1 x = x + 1


    type Type1() =
        member type1.method1() =
            printfn "type1.method1"
        member type1.method2() =
            printfn "type1.method2"


    [<Sealed>]
    type Type2() =
        member type2.method1() =
            printfn "type2.method1"
        member type2.method2() =
            printfn "type2.method2"

    [<Interface>]
    type InterfaceType1 =
        abstract member method1 : int -> int
        abstract member method2 : string -> unit

Lásd még