Sdílet prostřednictvím


Direktivy kompilátoru

Toto téma popisuje direktivy kompilátoru pro direktivy F# Interactive (dotnet fsi) viz Interactive Programming with F#.

Direktiva kompilátoru má předponu symbolu # a zobrazuje se na řádku samostatně.

Následující tabulka uvádí direktivy kompilátoru, které jsou k dispozici v jazyce F#.

Directive Description
#if if-expression Podporuje podmíněnou kompilaci. Kód v části za #if je zahrnut, pokud se výraz if-expression vyhodnotí na defined (viz níže).
#else Podporuje podmíněnou kompilaci. Označí část kódu, která se má zahrnout, pokud se symbol použitý s předchozím #if nehodnotí jako defined.
#endif Podporuje podmíněnou kompilaci. Označí konec podmíněného oddílu kódu.
#[řádek] int,
#[řádek] intstring,
#[řádek] intverbatim-string
Označuje původní řádek zdrojového kódu a název souboru pro ladění. Tato funkce je k dispozici pro nástroje, které generují zdrojový kód jazyka F#.
#nowarn warningcodes Zakáže jedno nebo více upozornění kompilátoru, jak je určeno kódy upozornění (viz níže).
#warnon warningcodes Povolí jedno nebo více upozornění kompilátoru, jak je určeno kódy upozornění (viz níže).

Direktivy podmíněné kompilace

Kód, který je deaktivován jednou z těchto direktiv, se v editoru visual Studio Code zobrazuje šedě.

Následující kód znázorňuje použití #ifdirektiv , #elsea #endif direktiv. V tomto příkladu kód obsahuje dvě verze definice function1. Pokud VERSION1 je definován pomocí parametru -define kompilátoru, je aktivován kód mezi #if direktivou a direktivou#else. V opačném případě je kód mezi #else a #endif aktivován.

#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

Direktiva #if také přijímá logické výrazy:

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

Lze použít následující výrazy.

if-expr vyhodnocení
if-expr1 \|\| if-expr2 defined pokud if-expr1 nebo if-expr2 je defined.
if-expr1 && if-expr2 defined pokud if-expr1 a if-expr2 jsou defined.
!if-expr1 defined pokud if-expr1 není defined.
( if-expr1 ) je definováno, pokud if-expr1 je definováno.
symbol defined pokud je to označeno jako definováno možností kompilátoru -define.

Logické operátory mají obvyklou logickou prioritu.

V jazyce F# neexistuje žádná #define direktiva kompilátoru. K definování symbolů používaných direktivou musíte použít možnost kompilátoru #if nebo nastavení projektu.

Direktivy podmíněné kompilace lze vnořit. Odsazení není pro direktivy kompilátoru významné.

Předdefinované symboly

Kompilátor F# a systém sestavení automaticky definují několik symbolů, které lze použít pro podmíněnou kompilaci.

Symboly konfigurace sestavení

Na základě konfigurace sestavení se definují následující symboly:

  • DEBUG: Definováno při kompilaci v režimu ladění. V systému DEBUG projektu se symbol automaticky definuje v konfiguraci ladění, ale ne v konfiguraci vydané verze. Tento symbol se běžně používá s kontrolními výrazy a diagnostickým kódem. Další informace naleznete v tématu Kontrolní výrazy.
  • TRACE: Definováno pro sestavení, která umožňují trasování. Podobně jako DEBUGtento symbol je obvykle definován v konfiguracích ladění, ale lze ho také povolit v konfiguracích vydaných verzí.

Tyto hodnoty můžete přepsat pomocí možnosti kompilátoru-define nebo nastavení projektu.

Symboly režimu kompilace

Následující symboly rozlišují různé režimy kompilace:

  • COMPILED: Definováno při kompilaci kódu pomocí kompilátoru jazyka F#. Tento symbol je užitečný, když potřebujete, aby se kód v kompilovaných sestaveních a relacích F# Interactive choval jinak.
  • INTERACTIVE: Definováno při kompilaci nebo spouštění kódu v jazyce F# Interactive (dotnet fsi), včetně interaktivních relací i spouštění skriptů. To umožňuje psát kód, který funguje jinak při interaktivním spuštění.

Další informace o použití těchto symbolů ve skriptech najdete v tématu Interaktivní programování pomocí jazyka F#.

Příklad:

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

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

Symboly cílové architektury

Systém sestavení také definuje symboly preprocesoru pro různé cílové architektury v projektech ve stylu sady SDK. Tyto symboly jsou užitečné při vytváření knihoven nebo aplikací, které cílí na více verzí .NET.

Cílové frameworky Symbols Další symboly
(dostupné v sadách SDK .NET 5+)
Symboly platformy (k dispozici pouze
při zadání TFM specifického pro operační systém)
.NET Framework NETFRAMEWORK, NET481, , , NET48NET472NET471NET47NET462NET461NET46NET452NET451NET45NET40NET35NET20 NET48_OR_GREATER, NET472_OR_GREATER, , NET471_OR_GREATER, NET47_OR_GREATERNET462_OR_GREATER, NET461_OR_GREATERNET46_OR_GREATERNET452_OR_GREATERNET451_OR_GREATERNET45_OR_GREATERNET40_OR_GREATER, NET35_OR_GREATERNET20_OR_GREATER
.NET Standard NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, NETSTANDARD1_6NETSTANDARD1_5, NETSTANDARD1_4NETSTANDARD1_3NETSTANDARD1_2, NETSTANDARD1_1NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER, NETSTANDARD2_0_OR_GREATER, , NETSTANDARD1_6_OR_GREATERNETSTANDARD1_5_OR_GREATERNETSTANDARD1_4_OR_GREATERNETSTANDARD1_3_OR_GREATERNETSTANDARD1_2_OR_GREATER, , NETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER
.NET 5+ (a .NET Core) NET, NET10_0, , , NET9_0NET8_0NET7_0NET6_0NET5_0NETCOREAPPNETCOREAPP3_1NETCOREAPP3_0NETCOREAPP2_2NETCOREAPP2_1NETCOREAPP2_0NETCOREAPP1_1NETCOREAPP1_0 NET10_0_OR_GREATER, NET9_0_OR_GREATER, , NET8_0_OR_GREATER, NET7_0_OR_GREATERNET6_0_OR_GREATER, NET5_0_OR_GREATERNETCOREAPP3_1_OR_GREATERNETCOREAPP3_0_OR_GREATERNETCOREAPP2_2_OR_GREATERNETCOREAPP2_1_OR_GREATERNETCOREAPP2_0_OR_GREATER, NETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER ANDROID, BROWSER, IOS, , MACCATALYSTMACOS, TVOS, , WINDOWS
[OS][version] (například IOS15_1),
[OS][version]_OR_GREATER (například IOS15_1_OR_GREATER)

Poznámka:

  • Symboly bez verzí se definují bez ohledu na verzi, na kterou cílíte.
  • Symboly specifické pro verzi jsou definované jenom pro verzi, na kterou cílíte.
  • Symboly <framework>_OR_GREATER jsou definované pro verzi, na kterou cílíte, a všechny předchozí verze. Pokud například cílíte na rozhraní .NET Framework 2.0, jsou definovány následující symboly: NET20, NET20_OR_GREATER, NET11_OR_GREATERa NET10_OR_GREATER.
  • Symboly NETSTANDARD<x>_<y>_OR_GREATER jsou definovány pouze pro cíle .NET Standard, a ne pro cíle, které implementují .NET Standard, jako jsou .NET Core a .NET Framework.
  • Liší se od cílových rámcových monikerů (TFMs) používaných vlastností MSBuild TargetFramework a NuGet.

Pomocí těchto symbolů můžete například podmíněně zkompilovat kód na základě cílové architektury:

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

Směrnice NULLABLE

Počínaje jazykem F# 9 můžete v projektu povolit odkazové typy s možnou hodnotou null:

<Nullable>enable</Nullable>

Tím se automaticky nastaví direktiva NULLABLE do sestavení. Při počátečním zavádění funkce je užitečné podmíněně měnit konfliktní kód pomocí direktiv hash #if NULLABLE:

#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

Direktivy řádků

Při sestavování kompilátor hlásí chyby v kódu jazyka F# odkazováním na čísla řádků, u kterých dojde k každé chybě. Tato čísla řádků začínají na 1 pro první řádek v souboru. Pokud ale generujete zdrojový kód jazyka F# z jiného nástroje, čísla řádků v generovaném kódu se obecně nezajímají, protože chyby ve generovaném kódu F# pravděpodobně vznikají z jiného zdroje. Direktiva #line poskytuje autorům nástrojů, které generují zdrojový kód jazyka F#, způsob předávání informací o původních číslech řádků a zdrojových souborech do generovaného kódu jazyka F#.

Při použití direktivy #line musí být názvy souborů uzavřeny do uvozovek. Pokud se před řetězcem nezobrazuje doslovný token (@), je nutné před řetězcem použít zpětné lomítko pomocí dvou zpětných lomítek namísto jednoho, aby je bylo možné použít v cestě. Následují platné tokeny řádků. V těchtopříkladch kódech předpokládáme, že v těchto příkladech je výsledkem původního souboru Script1 automaticky vygenerovaný automaticky vygenerovaný soubor F# a že kód v umístění těchto direktiv se vygeneruje z některých tokenů na řádku 25 v souboru Script1.

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

Tyto tokeny označují, že kód jazyka F# vygenerovaný v tomto umístění je odvozen z některých konstruktorů na řádku nebo blízko řádku 25 v Script1.

Všimněte si, že #line direktivy neovlivňují chování#nowarn / #warnon . Tyto dvě direktivy vždy spojují kompilovaný soubor.

Upozornění – direktivy

Direktivy pro upozornění zakazují nebo povolují zadaná upozornění kompilátoru pro části zdrojového souboru.

Direktiva warn je jeden řádek zdrojového kódu, který se skládá z

  • Volitelné úvodní prázdné znaky
  • Řetězec #nowarn nebo #warnon
  • Whitespace
  • Jedno nebo více kódů upozornění (viz níže) oddělené prázdnými znaky
  • Volitelné prázdné znaky
  • Volitelný řádkový komentář

Kód upozornění je posloupnost číslic (představující číslo upozornění), volitelně před znakem FS, volitelně obklopené dvojitými uvozovkami.

Direktiva #nowarn zakáže upozornění, dokud není nalezena direktiva #warnon pro stejné číslo upozornění, nebo do konce souboru. Podobně direktiva #nowarn zakáže varování, dokud se nenajde direktiva #warnon pro stejné číslo varování, nebo do konce souboru. Před a za těmito páry se použije výchozí nastavení kompilace, což je

  • žádné upozornění, pokud je zakázáno parametrem kompilátoru --nowarn (nebo příslušnou vlastností msbuild)
  • žádné upozornění pro upozornění výslovného souhlasu, pokud není povoleno parametrem kompilátoru --warnon (nebo příslušnou vlastností msbuild)

Tady je vykonstruovaný příklad.

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

Viz také