Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym temacie opisano dyrektywy kompilatora w przypadku dyrektyw F# Interactive (dotnet fsi), zobacz Interactive Programming with F#(Programowanie interakcyjne za pomocą języka F#).
Dyrektywa kompilatora jest poprzedzona symbolem # i jest wyświetlana w samym wierszu.
W poniższej tabeli wymieniono dyrektywy kompilatora, które są dostępne w języku F#.
| Directive | Description |
|---|---|
#if
wyrażenie-if |
Obsługuje kompilację warunkową. Kod w sekcji po #if jest zawarty, jeśli wyrażenie if ocenia się na defined (zobacz poniżej). |
#else |
Obsługuje kompilację warunkową. Oznacza sekcję kodu, która ma być uwzględniona, jeśli symbol użyty z poprzednim #if nie jest równy defined. |
#endif |
Obsługuje kompilację warunkową. Oznacza koniec sekcji warunkowej kodu. |
#[wiersz] int,#[wiersz] ciąg int,#[wiersz] intverbatim-string |
Wskazuje oryginalny wiersz kodu źródłowego i nazwę pliku na potrzeby debugowania. Ta funkcja jest udostępniana dla narzędzi, które generują kod źródłowy języka F#. |
#nowarn
kody ostrzegawcze |
Wyłącza co najmniej jedno ostrzeżenie kompilatora określone przez kody ostrzegawcze (patrz poniżej). |
#warnon
kody ostrzegawcze |
Włącza co najmniej jedno ostrzeżenie kompilatora określone przez kody ostrzegawcze (patrz poniżej). |
Dyrektywy kompilacji warunkowej
Kod dezaktywowany przez jedną z tych dyrektyw jest wyświetlany wygaszony w Edytorze programu Visual Studio Code.
Poniższy kod ilustruje użycie #ifdyrektyw , #elsei #endif . W tym przykładzie kod zawiera dwie wersje definicji function1. Gdy VERSION1 jest definiowana przy użyciu opcji -define kompilatora, kod między #if dyrektywą a dyrektywą #else jest aktywowany. W przeciwnym razie kod między elementami #else i #endif jest aktywowany.
#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
Dyrektywa #if akceptuje również wyrażenia logiczne:
#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG)
#endif
Można użyć następujących wyrażeń.
| wyrażenie-if | ocena |
|---|---|
if-expr1 \|\| if-expr2 |
defined jeśli if-expr1 lub if-expr2 jest defined. |
if-expr1 && if-expr2 |
defined jeśli if-expr1 i if-expr2 są defined. |
!if-expr1 |
defined jeśli if-expr1 nie defined. |
( if-expr1 ) |
zdefiniowane, jeśli if-expr1 jest zdefiniowane. |
symbol |
defined jeśli jest oznaczony jako zdefiniowany przez opcję kompilatora -define. |
Operatory logiczne mają zwykły pierwszeństwo logiczne.
Nie istnieje dyrektywa kompilatora #define w języku F#. Aby zdefiniować symbole używane przez dyrektywę #if , należy użyć opcji kompilatora lub ustawień projektu.
Dyrektywy kompilacji warunkowej można zagnieżdżać. Wcięcie nie jest istotne dla dyrektyw kompilatora.
Wstępnie zdefiniowane symbole
Kompilator języka F# i system kompilacji automatycznie definiują kilka symboli, których można użyć do kompilacji warunkowej.
Symbole konfiguracji kompilacji
Następujące symbole są definiowane na podstawie konfiguracji kompilacji:
-
DEBUG: zdefiniowane podczas kompilowania w trybie debugowania. W systemieDEBUGprojektu symbol jest automatycznie definiowany w konfiguracji debugowania, ale nie w konfiguracji wydania. Ten symbol jest często używany z asercji i kodu diagnostycznego. Aby uzyskać więcej informacji, zobacz Asercji. -
TRACE: zdefiniowana dla kompilacji, które umożliwiają śledzenie. Podobnie jakDEBUG, ten symbol jest zwykle definiowany w konfiguracjach debugowania, ale można go również włączyć w konfiguracjach wydania.
Te wartości można zastąpić przy użyciu opcji kompilatora-define lub ustawień projektu.
Symbole trybu kompilacji
Następujące symbole rozróżniają różne tryby kompilacji:
-
COMPILED: zdefiniowany podczas kompilowania kodu za pomocą kompilatora języka F#. Ten symbol jest przydatny, gdy potrzebny jest kod, aby zachowywał się inaczej w skompilowanych zestawach, a w sesjach interaktywnych języka F#. -
INTERACTIVE: zdefiniowany podczas kompilowania lub wykonywania kodu w języku F# Interactive (dotnet fsi), w tym sesji interakcyjnych i wykonywania skryptu. Dzięki temu można napisać kod, który działa inaczej podczas interakcyjnego uruchamiania.
Aby uzyskać więcej informacji na temat używania tych symboli w skryptach, zobacz Interactive Programming with F#(Programowanie interakcyjne za pomocą języka F#).
Przykład:
#if INTERACTIVE
// Code specific to F# Interactive
#r "nuget: Newtonsoft.Json"
#endif
#if COMPILED
// Code specific to compiled assemblies
open System.Configuration
#endif
Symbole platformy docelowej
System kompilacji definiuje również symbole preprocesora dla różnych platform docelowych w projektach w stylu zestawu SDK. Te symbole są przydatne podczas tworzenia bibliotek lub aplikacji przeznaczonych dla wielu wersji platformy .NET.
| Platformy docelowe | Symbols | Dodatkowe symbole (dostępne w zestawach SDK .NET 5+) |
Symbole platformy (dostępne tylko podczas określania formatu TFM specyficznego dla systemu operacyjnego) |
|---|---|---|---|
| .NET Framework |
NETFRAMEWORK, NET481, , , NET48NET472NET471NET47NET462NET461NET46NET452NET451NET45NET40NET35NET20 |
NET48_OR_GREATER, NET472_OR_GREATER, NET471_OR_GREATERNET47_OR_GREATERNET462_OR_GREATERNET461_OR_GREATERNET46_OR_GREATERNET452_OR_GREATERNET451_OR_GREATERNET45_OR_GREATERNET40_OR_GREATERNET35_OR_GREATERNET20_OR_GREATER |
|
| .NET Standard |
NETSTANDARD, NETSTANDARD2_1, , , NETSTANDARD2_0NETSTANDARD1_6NETSTANDARD1_5NETSTANDARD1_4NETSTANDARD1_3NETSTANDARD1_2NETSTANDARD1_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_GREATERNETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER |
|
| .NET 5+ (i .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_GREATERNET7_0_OR_GREATERNET6_0_OR_GREATERNET5_0_OR_GREATERNETCOREAPP3_1_OR_GREATERNETCOREAPP3_0_OR_GREATERNETCOREAPP2_2_OR_GREATERNETCOREAPP2_1_OR_GREATERNETCOREAPP2_0_OR_GREATERNETCOREAPP1_1_OR_GREATERNETCOREAPP1_0_OR_GREATER |
ANDROID, BROWSER, , IOS, MACCATALYSTMACOS, , TVOS, , WINDOWS[OS][version] (na przykład IOS15_1),[OS][version]_OR_GREATER (na przykład IOS15_1_OR_GREATER) |
Uwaga / Notatka
- Symbole bez wersji są definiowane niezależnie od wersji, na którą są kierowane.
- Symbole specyficzne dla wersji są definiowane tylko dla docelowej wersji.
- Symbole
<framework>_OR_GREATERsą definiowane dla docelowej wersji i wszystkich wcześniejszych wersji. Jeśli na przykład celem jest .NET Framework 2.0, zdefiniowane są następujące symbole:NET20,NET20_OR_GREATER,NET11_OR_GREATERiNET10_OR_GREATER. - Symbole
NETSTANDARD<x>_<y>_OR_GREATERsą definiowane tylko dla obiektów docelowych platformy .NET Standard, a nie dla obiektów docelowych implementujących platformę .NET Standard, takich jak .NET Core i .NET Framework. - Różnią się one od identyfikatorów frameworku docelowego (TFMs) używanych przez właściwość MSBuild i NuGet.
Na przykład można użyć tych symboli do warunkowego skompilowania kodu na podstawie platformy docelowej:
#if NET6_0_OR_GREATER
// Use .NET 6+ specific APIs
#else
// Use alternative implementation for older frameworks
#endif
Dyrektywa NULLABLE
Począwszy od F# 9, można włączyć typy referencyjne dopuszczające wartości null w projekcie.
<Nullable>enable</Nullable>
Spowoduje to automatyczne przypisanie do build dyrektywy NULLABLE. Jest to przydatne podczas początkowego wdrażania funkcji, aby warunkowo zmodyfikować konfliktowy kod za pomocą dyrektyw z hashem #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
Dyrektywy liniowe
Podczas kompilowania kompilator zgłasza błędy w kodzie języka F#, odwołując się do numerów wierszy, w których wystąpi każdy błąd. Te numery wierszy zaczynają się od 1 dla pierwszego wiersza w pliku. Jeśli jednak generujesz kod źródłowy języka F# z innego narzędzia, numery wierszy wygenerowanego kodu zwykle nie są interesujące, ponieważ błędy wygenerowanego kodu F# najprawdopodobniej wynikają z innego źródła. Dyrektywa #line zapewnia autorom narzędzi, które generują kod źródłowy języka F# w celu przekazywania informacji o oryginalnych numerach wierszy i plikach źródłowych do wygenerowanego kodu F#.
W przypadku korzystania z #line dyrektywy nazwy plików muszą być ujęte w cudzysłów. Chyba że token dosłowny (@) pojawia się przed ciągiem, należy użyć dwóch znaków ukośnika odwrotnego zamiast jednego, aby używać ich w ścieżce. Poniżej przedstawiono prawidłowe tokeny wiersza. W tych przykładach przyjęto założenie, że oryginalny plik Script1 powoduje automatyczne wygenerowanie pliku kodu F# podczas jego uruchamiania za pomocą narzędzia i że kod w lokalizacji tych dyrektyw jest generowany na podstawie niektórych tokenów w wierszu 25 w pliku Script1.
# 25
#line 25
#line 25 "C:\\Projects\\MyProject\\MyProject\\Script1"
#line 25 @"C:\Projects\MyProject\MyProject\Script1"
# 25 @"C:\Projects\MyProject\MyProject\Script1"
Te tokeny wskazują, że kod języka F# wygenerowany w tej lokalizacji pochodzi z niektórych konstrukcji znajdujących się w wierszu lub w pobliżu 25 .Script1
Należy zauważyć, że #line dyrektywy nie mają wpływu na zachowanie #nowarn / #warnon. Te dwie dyrektywy zawsze odnoszą się do skompilowanego pliku.
Ostrzegaj dyrektywy
Dyrektywy 'warn' wyłączają lub włączają określone ostrzeżenia kompilatora dla części pliku źródłowego.
Dyrektywa ostrzegawcze jest pojedynczym wierszem kodu źródłowego, który składa się z
- Opcjonalne białe znaki wiodące
- Ciąg
#nowarnlub#warnon - Whitespace
- Co najmniej jeden kod ostrzegawczy (patrz poniżej) oddzielony białym znakiem
- Opcjonalne odstępy
- Opcjonalny komentarz wiersza
Kod ostrzegawczy to sekwencja cyfr (reprezentująca numer ostrzeżenia), opcjonalnie poprzedzona FSznakiem , opcjonalnie otoczona podwójnymi cudzysłowami.
Dyrektywa #nowarn wyłącza ostrzeżenie, chyba że zostanie znaleziona dyrektywa #warnon dla tego samego numeru ostrzeżenia lub do końca pliku.
#nowarn Podobnie dyrektywa wyłącza ostrzeżenie do momentu #warnon znalezienia dyrektywy dla tego samego numeru ostrzeżenia lub do końca pliku. Przed i po takich parach zastosowanie ma ustawienie domyślne kompilacji, czyli
- brak ostrzeżenia, jeśli jest wyłączone przez opcję kompilatora --nowarn (lub odpowiednią właściwość msbuild)
- brak ostrzeżeń dla ostrzeżeń związanych z wyrażeniem zgody, chyba że włączono opcję kompilatora --warnon (lub odpowiednią właściwość msbuild)
Oto przykład (spisany).
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
Zobacz także
- Dokumentacja języka F#
- opcje kompilatora