다음을 통해 공유


컴파일러 지시문

이 항목에서는 F# Interactive(dotnet fsi) 지시문에 대한 컴파일러 지시문에 대해 설명합니다. F#을 사용한 대화형 프로그래밍을 참조하세요.

컴파일러 지시문에는 #기호 접두사로 지정되고 줄 자체에 나타납니다.

다음 표에서는 F#에서 사용할 수 있는 컴파일러 지시문을 나열합니다.

Directive Description
#if if-expression 조건부 컴파일을 지원합니다. #if 이후의 섹션에 있는 코드는 if-식defined로 평가될 때 포함됩니다(아래 참조).
#else 조건부 컴파일을 지원합니다. 이전 #if 과 함께 사용된 기호가 defined으로 평가되지 않을 경우 포함할 코드 섹션을 표시합니다.
#endif 조건부 컴파일을 지원합니다. 코드의 조건부 섹션이 끝나는 지점을 표시합니다.
#[줄] int,
#[줄] int문자열,
#[줄] intverbatim-string
디버깅을 위해 원본 소스 코드 줄과 파일 이름을 표시합니다. 이 기능은 F# 소스 코드를 생성하는 도구에서 사용할 수 있습니다.
#nowarn warningcodes 경고 코드로 지정된 컴파일러 경고를 하나 이상 사용하지 않도록 설정합니다(아래 참조).
#warnon warningcodes 경고 코드로 지정된 컴파일러 경고를 하나 이상 사용하도록 설정합니다(아래 참조).

조건부 컴파일 지시문

이러한 지시문 중 하나로 비활성화된 코드는 Visual Studio Code 편집기에서 흐리게 표시됩니다.

다음 코드에서는 #if, #else#endif 지시문을 사용하는 방법을 보여 줍니다. 이 예제의 코드에는 function1에 대한 두 가지 버전의 정의가 포함되어 있습니다. -define 컴파일러 옵션을VERSION1정의되는 경우 지시문과 지시문 사이의 #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 evaluation
if-expr1 \|\| if-expr2 definedif-expr1이거나 if-expr2일 때 defined.
if-expr1 && if-expr2 defined if-expr1if-expr2defined인 경우.
!if-expr1 definedif-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 버전을 대상으로 하는 라이브러리 또는 애플리케이션을 만들 때 유용합니다.

대상 프레임워크 기호 추가 기호
(.NET 5+ SDK에서 사용 가능)
플랫폼 기호 (제한적으로만 제공)
운영 체제에 특화된 TFM을 지정할 때)
.NET Framework NETFRAMEWORK, NET481, NET48, NET472, NET471, NET47, , NET462NET461, NET46, NET452, NET451NET45NET40NET35,NET20 NET48_OR_GREATER, NET472_OR_GREATER,NET471_OR_GREATER, NET47_OR_GREATER, NET462_OR_GREATER, NET461_OR_GREATER, NET46_OR_GREATER, NET452_OR_GREATER, NET451_OR_GREATER, NET45_OR_GREATER, NET40_OR_GREATER, NET35_OR_GREATER, NET20_OR_GREATER
.NET Standard NETSTANDARD, NETSTANDARD2_1, NETSTANDARD2_0, NETSTANDARD1_6, NETSTANDARD1_5, NETSTANDARD1_4, NETSTANDARD1_3NETSTANDARD1_2, NETSTANDARD1_1NETSTANDARD1_0 NETSTANDARD2_1_OR_GREATER,NETSTANDARD2_0_OR_GREATER, NETSTANDARD1_6_OR_GREATER, NETSTANDARD1_5_OR_GREATER, NETSTANDARD1_4_OR_GREATER, NETSTANDARD1_3_OR_GREATERNETSTANDARD1_2_OR_GREATER, NETSTANDARD1_1_OR_GREATERNETSTANDARD1_0_OR_GREATER
.NET 5 이상(및 .NET Core) NET, NET10_0, NET9_0, NET8_0, NET7_0, NET6_0, , NET5_0NETCOREAPP, NETCOREAPP3_1, NETCOREAPP3_0, NETCOREAPP2_2NETCOREAPP2_1NETCOREAPP2_0NETCOREAPP1_1,NETCOREAPP1_0 NET10_0_OR_GREATER, NET9_0_OR_GREATER,NET8_0_OR_GREATER, NET7_0_OR_GREATER, NET6_0_OR_GREATER, NET5_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_GREATER, NETCOREAPP1_0_OR_GREATER ANDROID, BROWSER, IOS, MACCATALYST, MACOS, TVOS, WINDOWS
[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 Core 및 .NET Framework와 같은 .NET Standard를 구현하는 대상에는 정의되지 않습니다.
  • 이는 MSBuild TargetFramework 속성NuGet에서 사용되는 대상 프레임워크 모니커(TFM)와 다릅니다.

예를 들어 다음 기호를 사용하여 대상 프레임워크에 따라 코드를 조건부로 컴파일할 수 있습니다.

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

NULLABLE 지시문

F# 9부터 프로젝트에서 nullable 참조 형식을 사용하도록 설정할 수 있습니다.

<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

줄 지시문

빌드 과정에서 컴파일러를 통해 F# 코드의 오류를 보고할 때는 각 오류의 발생 지점에 해당하는 줄 번호가 참조 정보로 사용됩니다. 이러한 줄 번호는 1부터 시작합니다. 파일의 맨 첫 줄이 1번입니다. 그러나 다른 도구를 사용하여 F# 소스 코드를 생성하는 경우에는 생성된 코드의 줄 번호가 일반적으로 크게 중요하지 않습니다. 생성된 F# 코드의 오류가 다른 소스에서 발생한 것일 가능성이 높기 때문입니다. #line 지시문을 사용하면 다른 도구를 통해 F# 소스 코드를 생성할 때 원래 줄 번호와 소스 파일에 대한 정보를 생성된 F# 코드에 전달할 수 있습니다.

#line 지시문을 사용하는 경우 파일 이름을 따옴표로 묶어야 합니다. 문자열 앞에 축자 토큰(@)이 오지 않는 경우 백슬래시 문자를 경로에 사용하려면 한 개가 아닌 두 개의 백슬래시 문자를 사용하여 이를 이스케이프해야 합니다. 다음은 유효한 줄 토큰입니다. 이 예제에서는 도구를 사용하여 원래 파일 Script1을 실행한 결과로 F# 코드 파일이 자동 생성되며 이러한 지시문이 있는 위치의 코드가 파일 Script1의 25번 줄에 있는 몇몇 토큰으로부터 생성되는 것으로 가정합니다.

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

이 토큰은 해당 위치에서 생성되는 F# 코드가 25Script1번 줄 또는 그 부근에 있는 몇몇 구문으로부터 파생됨을 나타냅니다.

지시문 #line#nowarn / #warnon의 동작에 영향을 미치지 않습니다. 이러한 두 지시문은 항상 컴파일되는 파일과 관련이 있습니다.

경고 지시문

경고 지시문은 소스 파일의 일부에 대해 지정된 컴파일러 경고를 비활성화하거나 활성화합니다.

경고 지시문은 한 줄의 소스 코드로 구성됩니다.

  • 선택적 선행 공백
  • 문자열 #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

참고하십시오