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


Fordítói irányelvek

Ez a témakör a fordítói irányelveket ismerteti, az F# Interaktív (dotnet fsi) direktívák esetében lásd: Interaktív programozás az F#-tal.

A fordító utasításait a # szimbólummal előtagolják, és önállóan jelennek meg egy sorban.

Az alábbi táblázat az F#-ban elérhető fordítói irányelveket sorolja fel.

Directive Description
#if if-expression Támogatja a feltételes fordítást. A kód a #if utáni szakaszban szerepel, ha az if-kifejezés értéke defined (lásd alább).
#else Támogatja a feltételes fordítást. Megjelöl egy kódrészt, amelyet bele kell foglalni, ha a korábbi #if-hez használt szimbólum nem felel meg a(z) defined értéknek.
#endif Támogatja a feltételes fordítást. A kód feltételes szakaszának végét jelöli.
#[sor] int,
#[sor] int sztring,
#[sor] intverbatim-string
A hibakereséshez az eredeti forráskódsort és fájlnevet jelzi. Ez a funkció az F#-forráskódot létrehozó eszközökhöz érhető el.
#nowarn warningcodes Letilt egy vagy több fordítói figyelmeztetést a figyelmeztető kódok által megadottak szerint (lásd alább).
#warnon warningcodes Engedélyezi a figyelmeztető kódok által megadott egy vagy több fordítói figyelmeztetést (lásd alább).

Feltételes fordítási irányelvek

Az ezen irányelvek egyikével inaktivált kód halványan jelenik meg a Visual Studio Code Editorban.

Az alábbi kód a , #ifés #else az #endifirányelvek használatát mutatja be. Ebben a példában a kód a definíció function1két verzióját tartalmazza. Ha VERSION1 a -define fordítóbeállítással van definiálva, az irányelv és az #if#else irányelv közötti kód aktiválódik. Ellenkező esetben a kód a kettő között #else van, és #endif aktiválva van.

#if VERSION1
let function1 x y =
   printfn "x: %d y: %d" x y
   x + 2 * y
#else
let function1 x y =
   printfn "x: %d y: %d" x y
   x - 2*y
#endif

let result = function1 10 20

Az #if irányelv a következő logikai kifejezéseket is elfogadja:

#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG)
#endif

A következő kifejezések használhatók.

if-expr kiértékelés
if-expr1 \|\| if-expr2 defined ha if-expr1 vagy if-expr2 van defined.
if-expr1 && if-expr2 defined ha if-expr1 és if-expr2 vannak defined.
!if-expr1 defined ha if-expr1 nem defined.
( if-expr1 ) if-expr1 akkor van definiálva, ha definiálva van.
symbol defined ha a -define fordító opció által meghatározott módon van megjelölve.

A logikai operátorok a szokásos logikai elsőbbséget élvezik.

Az F#-ban nincs #define fordítási irányelv. Az irányelv által használt szimbólumok meghatározásához a fordító vagy a projekt beállításait kell használnia #if .

A feltételes fordítási irányelvek beágyazhatók. A behúzás a fordítói irányelvek esetében nem jelentős.

Előre definiált szimbólumok

Az F#-fordító és -buildrendszer automatikusan meghatároz több szimbólumot, amelyek felhasználhatók a feltételes fordításhoz.

Konfigurációs szimbólumok létrehozása

A buildkonfiguráció alapján a következő szimbólumok vannak definiálva:

  • DEBUG: Hibakeresési módban történő fordításkor definiálva. A projektrendszerben a rendszer automatikusan definiálja a DEBUG szimbólumot a hibakeresési konfigurációban, a Kiadás konfigurációban azonban nem. Ezt a szimbólumot gyakran használják az állításokkal és a diagnosztikai kóddal. További információ: Helyességi állítások.
  • TRACE: A nyomkövetést engedélyező buildekhez van definiálva. Ez DEBUGa szimbólum általában hibakeresési konfigurációkban van definiálva, de a kiadási konfigurációkban is engedélyezhető.

Ezeket az értékeket felülbírálhatja a fordító vagy a-define projekt beállításaival.

Fordítási mód szimbólumai

A következő szimbólumok megkülönböztetik a különböző fordítási módokat:

  • COMPILED: Kód F#-fordítóval való összeállításakor definiálva. Ez a szimbólum akkor hasznos, ha kódra van szüksége, hogy másképp viselkedjen a lefordított szerelvényekben és az F# interaktív munkamenetekben.
  • INTERACTIVE: A kód F# Interactive () nyelven történő összeállításakor vagy végrehajtásakor definiálva,dotnet fsi beleértve az interaktív munkameneteket és a szkriptek végrehajtását is. Ez lehetővé teszi, hogy interaktív futtatáskor eltérően működő kódot írjon.

További információ a szimbólumok szkriptekben való használatáról: Interaktív programozás F#-tal.

Példa:

#if INTERACTIVE
// Code specific to F# Interactive
#r "nuget: Newtonsoft.Json"
#endif

#if COMPILED
// Code specific to compiled assemblies
open System.Configuration
#endif

Cél keretrendszerszimbólumok

A buildelési rendszer az SDK-stílusú projektek különböző cél-keretrendszereinek előprocesszorszimbólumait is meghatározza. Ezek a szimbólumok akkor hasznosak, ha több .NET-verziót célzó kódtárakat vagy alkalmazásokat hoznak létre.

Cél-keretrendszerek Symbols További szimbólumok
(.NET 5+ SDK-kban érhető el)
Platformszimbólumok (csak elérhető)
operációsrendszer-specifikus TFM megadásakor)
.NET-keretrendszer NETFRAMEWORK, NET481, NET48, NET472, NET471, NET47NET462, NET461, NET46, NET452, NET451, NET45, , NET40, , , NET35NET20 NET48_OR_GREATER, NET472_OR_GREATER, NET471_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATERNET461_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATER, NET451_OR_GREATER, NET45_OR_GREATER, NET40_OR_GREATER, , , NET35_OR_GREATERNET20_OR_GREATER
.NET Standard NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5NETSTANDARD1_4, NETSTANDARD1_3, NETSTANDARD1_2, , NETSTANDARD1_1NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER, NETSTANDARD2_0_OR_GREATER, NETSTANDARD1_6_OR_GREATER, NETSTANDARD1_5_OR_GREATERNETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATER, NETSTANDARD1_2_OR_GREATER, , NETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER
.NET 5+ (és .NET Core) NET, NET10_0, NET9_0, NET8_0, NET7_0, NET6_0NET5_0, NETCOREAPP, NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_2, NETCOREAPP2_1, , NETCOREAPP2_0, , , NETCOREAPP1_1NETCOREAPP1_0 NET10_0_OR_GREATER, NET9_0_OR_GREATER, NET8_0_OR_GREATER, NET7_0_OR_GREATER, NET6_0_OR_GREATERNET5_0_OR_GREATER, NETCOREAPP3_1_OR_GREATER, NETCOREAPP3_0_OR_GREATER, NETCOREAPP2_2_OR_GREATER, NETCOREAPP2_1_OR_GREATER, NETCOREAPP2_0_OR_GREATER, , , NETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER ANDROID, BROWSER, IOS, MACCATALYSTMACOS, TVOS, WINDOWS
[OS][version] (például IOS15_1),
[OS][version]_OR_GREATER (például IOS15_1_OR_GREATER)

Megjegyzés:

  • A verzió nélküli szimbólumok a megcélzott verziótól függetlenül vannak definiálva.
  • A verzióspecifikus szimbólumok csak a megcélzott verzióhoz vannak definiálva.
  • A <framework>_OR_GREATER szimbólumok a megcélzott verzióhoz és az összes korábbi verzióhoz vannak definiálva. Ha például a 2.0-s .NET-keretrendszert célozza meg, a következő szimbólumok vannak definiálva: NET20, NET20_OR_GREATER, NET11_OR_GREATER, és NET10_OR_GREATER.
  • A NETSTANDARD<x>_<y>_OR_GREATER szimbólumok csak a .NET Standard célokhoz vannak definiálva, a .NET Standardot implementáló célokhoz nem, például a .NET Core-hoz és a .NET-keretrendszer.
  • Ezek eltérnek az MSBuild TargetFramework tulajdonság és a NuGet által használt célkeret-monikerektől (TFM-ek).

Ezeket a szimbólumokat használhatja például a kód feltételes fordítására a cél keretrendszer alapján:

#if NET6_0_OR_GREATER
// Use .NET 6+ specific APIs
#else
// Use alternative implementation for older frameworks
#endif

NULLABLE direktíva

Az F# 9-től kezdve engedélyezheti a null értékű hivatkozástípusokat a projektben:

<Nullable>enable</Nullable>

Ez automatikusan beállítja a NULLABLE irányelvet a buildhez. A funkció első bevezetésekor hasznos, ha feltételes logika alkalmazásával módosítja az ütköző kódot #if NULLABLE hash direktívák alapján:

#if NULLABLE 
let length (arg: 'T when 'T: not null) =
    Seq.length arg
#else
let length arg =
    match arg with
    | null -> -1
    | s -> Seq.length s
#endif

Vonalirányok

Az összeállítás során a fordító az F#-kód hibáit jelenti, és hivatkozik azokra a sorszámokra, amelyeken az egyes hibák előfordulnak. Ezek a sorok a fájl első sorához 1-nél kezdődnek. Ha azonban F# forráskódot hoz létre egy másik eszközről, a létrehozott kód sorszámai általában nem érdekesek, mivel a generált F# kód hibái valószínűleg egy másik forrásból származnak. Az #line irányelv lehetővé teszi az F#-forráskódot létrehozó eszközök szerzői számára, hogy az eredeti vonalszámokra és forrásfájlokra vonatkozó információkat átadják a létrehozott F# kódnak.

Az irányelv használatakor a #line fájlneveket idézőjelek közé kell foglalni. Ha a szó szerinti jogkivonat (@) nem jelenik meg a sztring előtt, a fordított perjel karakterei elől két fordított perjel karaktert kell használnia az elérési úton való használatukhoz. Az alábbiak érvényes vonaljogkivonatok. Ezekben a példákban feltételezzük, hogy az eredeti fájl Script1 egy automatikusan létrehozott F# kódfájlt eredményez, amikor egy eszközön fut, és hogy az irányelvek helyén található kód a fájl Script125. sorában lévő egyes jogkivonatokból jön létre.

# 25
#line 25
#line 25 "C:\\Projects\\MyProject\\MyProject\\Script1"
#line 25 @"C:\Projects\MyProject\MyProject\Script1"
# 25 @"C:\Projects\MyProject\MyProject\Script1"

Ezek a jogkivonatok azt jelzik, hogy az ezen a helyen létrehozott F#-kód néhány, a sorban vagy annak 25Script1közelében lévő szerkezetből származik.

Vegye figyelembe, hogy az #line direktívák nem befolyásolják a #nowarn / #warnon. Ez a két irányelv mindig a fordítás alatt álló fájlhoz kapcsolódik.

Figyelmeztetési irányelvek

A figyelmeztetési irányelvek letiltják vagy engedélyezik a forrásfájl egyes részeire vonatkozó megadott fordítói figyelmeztetéseket.

A figyelmeztetési irányelv a forráskód egyetlen sora, amely a következőből áll:

  • Választható kezdő szóköz
  • A karakterlánc #nowarn vagy #warnon
  • Whitespace
  • Egy vagy több figyelmeztető kód (lásd alább), szóközök szerint elválasztva
  • Nem kötelező üres tér
  • Opcionális sorhozzászólás

A figyelmeztető kód számjegyek sorozata (a figyelmeztető számnak megfelelően), opcionálisan megelőzve FS, opcionálisan idézőjelekkel körülvéve.

A #nowarn utasítás letiltja a figyelmeztetést, amíg nem talál egy #warnon utasítást ugyanazzal a figyelmeztetési számmal, vagy a fájl végéig. Hasonlóképpen, az #nowarn irányelv letiltja a figyelmeztetést, amíg #warnon irányelv nem található ugyanahhoz a figyelmeztetés számához, vagy a fájl végéig. Az ilyen párok előtt és után az összeállítás alapértelmezése érvényes, ami

  • nincs figyelmeztetés, ha egy --nowarn fordítóbeállítás (vagy a megfelelő msbuild tulajdonság) letiltja
  • nincs figyelmeztetés a bejelentkezési figyelmeztetésekre, kivéve, ha a --warnon fordítóbeállítás (vagy a megfelelő msbuild tulajdonság) engedélyezi

Íme egy mesterséges példa.

module A
match None with None -> ()     // warning
let x =
    #nowarn 25
    match None with None -> 1  // no warning
    #warnon FS25
match None with None -> ()     // warning
#nowarn "FS25" FS007 "42"
match None with None -> ()     // no warning

Lásd még