Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
В этом разделе описываются директивы компилятора для директив F# Interactive (dotnet fsi) см. статью "Интерактивное программирование с помощью F#".
Директива компилятора префиксируется символом #и отображается в строке.
В следующей таблице перечислены директивы компилятора, доступные в F#.
| Directive | Description |
|---|---|
#if
if-expression |
Поддерживает условную компиляцию. Код в разделе после #if включён, если выражение if оценивается как defined (см. ниже). |
#else |
Поддерживает условную компиляцию. Отмечает раздел кода для включения, если символ, используемый с предыдущим #if, не соответствует defined. |
#endif |
Поддерживает условную компиляцию. Помечает конец условного раздела кода. |
#[строка] int,#[строка] intstring,#[строка] intverbatim-string |
Указывает исходную строку кода и имя файла для отладки. Эта возможность предназначена для средств, создающих исходный код F#. |
#nowarn
коды предупреждений |
Отключает одно или несколько предупреждений компилятора, указанных в кодах предупреждений (см. ниже). |
#warnon
коды предупреждений |
Включает одно или несколько предупреждений компилятора, указанных в кодах предупреждений (см. ниже). |
Директивы условной компиляции
Код, деактивированный одной из этих директив, отображается неактивным в редакторе Visual Studio Code.
В следующем коде демонстрируется применение директив #if, #else и #endif. В данном примере код содержит две версии определения function1. При VERSION1 определении с помощью параметра компилятора -define код между #if директивой и #else директивой активируется. В противном случае активируется код между директивами #else и #endif.
#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
Директива #if также принимает логические выражения:
#if SILVERLIGHT || COMPILED && (NETCOREFX || !DEBUG)
#endif
Можно использовать следующие выражения.
| if-expr | оценка |
|---|---|
if-expr1 \|\| if-expr2 |
defined если if-expr1 или if-expr2defined. |
if-expr1 && if-expr2 |
defined если if-expr1 и if-expr2 являются defined. |
!if-expr1 |
defined если if-expr1 не defined. |
( if-expr1 ) |
определяется, если if-expr1 определен. |
symbol |
defined если указано как определено параметром компилятора -define. |
Логические операторы имеют обычный логический приоритет.
В F# отсутствует директива компилятора #define. Вы должны использовать параметр компилятора или параметры проекта для определения символов, используемых директивой #if.
Директивы условной компиляции не могут быть вложенными. Отступ не имеет значения для директив компилятора.
Стандартные символы
Компилятор F# и система сборки автоматически определяют несколько символов, которые можно использовать для условной компиляции.
Символы конфигурации сборки
Следующие символы определяются на основе конфигурации сборки:
-
DEBUG: определяется при компиляции в режиме отладки. В системеDEBUGпроекта символ автоматически определяется в конфигурации отладки, но не в конфигурации выпуска. Этот символ часто используется с утверждениями и диагностическим кодом. Дополнительные сведения см. в разделе "Утверждения". -
TRACE: определено для сборок, которые обеспечивают трассировку. НапримерDEBUG, этот символ обычно определяется в конфигурациях отладки, но также может быть включен в конфигурациях выпуска.
Эти значения можно переопределить с помощью -define параметра компилятора или параметров проекта.
Символы режима компиляции
Следующие символы различаются между различными режимами компиляции:
-
COMPILED: определяется при компиляции кода с помощью компилятора F#. Этот символ полезен, если вам нужен код для поведения по-разному в скомпилированных сборках и интерактивных сеансах F#. -
INTERACTIVE: определяется при компиляции или выполнении кода в F# Interactive (dotnet fsi), включая интерактивные сеансы и выполнение скрипта. Это позволяет писать код, который работает по-разному при интерактивном выполнении.
Дополнительные сведения об использовании этих символов в скриптах см. в статье "Интерактивное программирование с помощью F#".
Пример:
#if INTERACTIVE
// Code specific to F# Interactive
#r "nuget: Newtonsoft.Json"
#endif
#if COMPILED
// Code specific to compiled assemblies
open System.Configuration
#endif
Символы целевой платформы
Система сборки также определяет символы препроцессора для различных целевых платформ в проектах в стиле ПАКЕТА SDK. Эти символы полезны при создании библиотек или приложений, предназначенных для нескольких версий .NET.
| Целевые фреймворки | Символы | Дополнительные символы (доступно в пакетах SDK для .NET 5 и более поздних версий) |
Символы платформы (доступны только при указании TFM для конкретной ОС) |
|---|---|---|---|
| Платформа .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_GREATERNETSTANDARD1_6_OR_GREATERNETSTANDARD1_5_OR_GREATERNETSTANDARD1_4_OR_GREATERNETSTANDARD1_3_OR_GREATERNETSTANDARD1_2_OR_GREATERNETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER |
|
| .NET 5+ (и .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, IOSMACCATALYSTMACOSTVOSWINDOWS[OS][version] (например IOS15_1),[OS][version]_OR_GREATER (например IOS15_1_OR_GREATER) |
Замечание
- Символы без привязки к версии определены независимо от версии, которую вы хотите использовать в качестве целевой.
- Символы, специфичные для версии, определены только для той версии, на которую вы нацеливаетесь.
- Символы
<framework>_OR_GREATERопределены для версии, которую вы хотите использовать в качестве целевой, и всех более ранних версий. Например, если вы выбрали .NET Framework 2.0, определяются следующие символы:NET20,NET20_OR_GREATER,NET11_OR_GREATERиNET10_OR_GREATER. -
NETSTANDARD<x>_<y>_OR_GREATERСимволы определяются только для целевых объектов .NET Standard, а не для целевых объектов, реализующих .NET Standard, таких как .NET Core и платформа .NET Framework. - Они отличаются от моникеров целевой платформы (TFM), используемых свойством
TargetFrameworkи NuGet.
Например, эти символы можно использовать для условной компиляции кода на основе целевой платформы:
#if NET6_0_OR_GREATER
// Use .NET 6+ specific APIs
#else
// Use alternative implementation for older frameworks
#endif
Директива NULLABLE
Начиная с F# 9, в проекте можно включить ссылочные типы, допускающие значение NULL:
<Nullable>enable</Nullable>
Это автоматически устанавливает директиву NULLABLE в сборке. Это полезно при первоначальном развертывании функции, чтобы условно изменить конфликтующий код с помощью директив хэша #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
Директивы line
При сборке компилятор сообщает об ошибках в коде F #, ссылаясь на номера строк, в которых возникли ошибки. Номера строк начинаются с 1 для первой строки в файле. Тем не менее при создании исходного кода F# из другого средства номера строк в сформированном коде обычно не представляют интереса, поскольку ошибки в сформированном коде F#, скорее всего, проистекают из другого источника. Директива #line позволяет разработчикам средств, формирующих исходный код F#, передавать сведения о номерах исходных строк и исходных файлах в сформированный код F#.
При использовании директивы #line необходимо заключать имена файлов в кавычки. Если в начале строки не указывается токен verbatim (@), то чтобы использовать в пути символы обратной косой черты, необходимо их экранировать, указывая две обратные косые черты вместо одной. Далее приводятся допустимые токены строк. В этих примерах предполагается, что исходный файл Script1 при запуске в соответствующем средстве приводит к автоматическому созданию файла кода F# и что код в месте расположения этих директив формируется из некоторых токенов в строке 25 файла Script1.
# 25
#line 25
#line 25 "C:\\Projects\\MyProject\\MyProject\\Script1"
#line 25 @"C:\Projects\MyProject\MyProject\Script1"
# 25 @"C:\Projects\MyProject\MyProject\Script1"
Эти токены указывают, что код F#, сформированный в этом месте, является производным от некоторых конструкций в строке 25 или рядом с ней в файле Script1.
Обратите внимание, что #line директивы не влияют на поведение #nowarn / #warnon. Эти две директивы всегда связаны с скомпилированным файлом.
Директивы Warn
Директивы Warn отключают или включают указанные предупреждения компилятора для определённых частей исходного файла.
Директива warn — это одна строка исходного кода, состоящая из
- Необязательные начальные пробелы
- Строка
#nowarnили#warnon - Whitespace
- Один или несколько кодов предупреждений (см. ниже), разделенных пробелами
- Необязательное пробелы
- Необязательный строковый комментарий
Код предупреждения — это последовательность цифр (представляющая номер предупреждения), которая при необходимости может начинаться с FS и при необходимости может быть окружена двойными кавычками.
#nowarn Директива отключает предупреждение до тех пор, пока не будет найдена #warnon директива для того же номера предупреждения, либо до конца файла. Аналогичным образом, #nowarn директива отключает предупреждение до тех пор, пока не будет найдена #warnon директива для одного и того же номера предупреждения или до конца файла. До и после таких пар применяется компиляция по умолчанию.
- Нет предупреждений, если они отключены с помощью параметра компилятора --nowarn (или соответствующего свойства MSBuild)
- нет предупреждений о предупреждениях при согласии, если не включен параметр компилятора --warnon (или соответствующее свойство msbuild)
Вот (выдуманный) пример.
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
См. также
- Справочник по языку F#
- Параметры компилятора