Null 값

이 항목에서는 F#에서 null 값을 사용하는 방법을 설명합니다.

F# 9 이전의 Null 값

Null 값은 일반적으로 F#에서 값 또는 변수에 사용되지 않습니다. 그러나 null은 특정 상황에서 비정상적인 값으로 나타납니다. 형식이 F#에 정의된 경우 AllowNullLiteral 특성이 형식에 적용되지 않는 한 null은 일반 값으로 허용되지 않습니다. 형식이 다른 .NET 언어로 정의된 경우 null은 가능한 값이며 이러한 형식과 상호 운용하는 경우 F# 코드에 null 값이 발생할 수 있습니다.

F#에서 정의되고 F#에서 엄격하게 사용되는 형식의 경우 F# 라이브러리를 사용하여 null 값을 직접 만드는 유일한 방법은 Unchecked.defaultof 또는 Array.zeroCreate사용하는 것입니다. 그러나 다른 .NET 언어에서 사용되는 F# 형식의 경우 또는 .NET Framework와 같이 F#으로 작성되지 않은 API와 함께 해당 형식을 사용하는 경우 null 값이 발생할 수 있습니다.

다른 .NET 언어에서 가능한 null 값이 있는 참조 변수를 사용할 수 있는 경우 F#에서 option 형식을 사용할 수 있습니다. F# option 형식의 null 대신 개체가 없는 경우 옵션 값 None 사용합니다. 객체가 있을 때 객체 Some(obj)에 옵션 값 obj을 사용합니다. 자세한 내용은 옵션참조하세요. 주의하세요, null에서 Some x가 x인 경우, 여전히 null 값을 Option에 포함시킬 수 있습니다. 이 때문에 값이 None때 null 사용하는 것이 중요합니다.

null 키워드는 F#의 유효한 키워드이며. .NET Framework API 또는 다른 .NET 언어로 작성된 다른 API로 작업할 때 사용해야 합니다. null 값이 필요할 수 있는 두 가지 상황은 .NET API를 호출하고 null 값을 인수로 전달하는 경우와 .NET 메서드 호출에서 반환 값 또는 출력 매개 변수를 해석할 때입니다.

null 값을 .NET 메서드에 전달하려면 호출 코드에서 null 키워드만 사용합니다. 다음 코드 예제에서는 이를 보여 줍니다.

open System

// Pass a null value to a .NET method.
let ParseDateTime (str: string) =
    let (success, res) =
        DateTime.TryParse(str, null, System.Globalization.DateTimeStyles.AssumeUniversal)

    if success then Some(res) else None

.NET 메서드에서 가져온 null 값을 해석하려면 가능한 경우 패턴 일치를 사용합니다. 다음 코드 예제에서는 패턴 일치를 사용하여 입력 스트림의 끝을 지나 읽으려고 할 때 ReadLine 반환되는 null 값을 해석하는 방법을 보여 줍니다.

// Open a file and create a stream reader.
let fileStream1 =
    try
        System.IO.File.OpenRead("TextFile1.txt")
    with :? System.IO.FileNotFoundException ->
        printfn "Error: TextFile1.txt not found."
        exit (1)

let streamReader = new System.IO.StreamReader(fileStream1)

// ProcessNextLine returns false when there is no more input;
// it returns true when there is more input.
let ProcessNextLine nextLine =
    match nextLine with
    | null -> false
    | inputString ->
        match ParseDateTime inputString with
        | Some(date) -> printfn "%s" (date.ToLocalTime().ToString())
        | None -> printfn "Failed to parse the input."

        true

// A null value returned from .NET method ReadLine when there is
// no more input.
while ProcessNextLine(streamReader.ReadLine()) do
    ()

F# 형식의 널 값은 Array.zeroCreate을 호출하는 Unchecked.defaultof을 사용할 때와 같은 다른 방법으로도 생성될 수 있습니다. null 값을 캡슐화 상태로 유지하려면 이러한 코드에 주의해야 합니다. F#용 라이브러리에서는 모든 함수에서 null 값을 확인할 필요가 없습니다. 다른 .NET 언어와의 상호 운용을 위해 라이브러리를 작성하는 경우 C# 또는 Visual Basic 코드와 마찬가지로 null 입력 매개 변수에 대한 검사를 추가하고 ArgumentNullExceptionthrow해야 할 수 있습니다.

다음 코드를 사용하여 임의의 값이 null인지 확인할 수 있습니다.

match box value with
| null -> printf "The value is null."
| _ -> printf "The value is not null."

F# 9로 시작하는 null 값들

F# 9에서는 null 값으로 사용할 수 있는 참조 형식을 처리하기 위해 언어에 추가 기능이 추가됩니다. 이러한 속성은 기본적으로 꺼져 있습니다. 설정하려면 프로젝트 파일에 다음 속성을 넣어야 합니다.

<Nullable>enable</Nullable>

그러면 --checknulls+플래그 F# 컴파일러에 전달하고 빌드에 대한 NULLABLE전처리기 지시문 설정합니다.

Null 허용 여부로 명시적으로 옵트인하려면 형식 선언에 새 구문 접미사가 추가되어야 합니다.

type | null

막대 기호 | 구문에서 논리적 OR의 의미를 가지며, 기본 형식과 nullable 참조라는 두 개의 비연속 형식 집합의 합합을 작성합니다. F# 구분된 합집합의 여러 사례를 선언하는 데 사용되는 것과 동일한 구문 기호입니다. type AB = A | B는 A또는 B의 의미를 가집니다.

모든 참조 유형이 일반적으로 사용되는 위치에 nullable 주석 | null를 사용할 수 있습니다.

  • 유니온 타입, 레코드 타입, 사용자 정의 타입의 필드.
  • 기존 형식에 대한 형식 별칭입니다.
  • 제네릭 형식의 애플리케이션을 입력합니다.
  • 바인딩, 매개 변수 또는 반환 형식을 허용하기 위한 명시적 형식 주석입니다.
  • 멤버, 속성 또는 필드와 같은 개체 프로그래밍 구문에 주석을 입력합니다.
type AB = A | B
type AbNull = AB | null

type RecordField = { X: string | null }
type TupleField = string * string | null

type NestedGenerics = { Z : List<List<string | null> | null> | null }

기호 |는 F#에서 다른 용도로 사용될 수 있으며, 이는 구문적 모호성을 초래할 수 있습니다. 이러한 경우, null 주석이 추가된 형식 주위에 괄호가 필요합니다.

// Unexpected symbol '|' (directly before 'null') in member definition
type DUField = N of string | null

동일한 형식을 한 쌍의 ( ) 괄호로 래핑하면 문제가 해결됩니다.

type DUField = N of (string | null)

패턴 일치에 사용되는 경우 | 서로 다른 패턴 일치 절을 구분하는 데 사용됩니다.

match x with
| ?: string | null -> ...

이 코드 조각은 실제로 코드가 먼저 string 형식에 대해 형식 테스트를 수행한 다음 null 처리를 위한 별도의 절을 갖는 코드와 동일합니다.

match x with
| ?: string 
| null -> ...

중요하다

상호 운용성을 위해 추가 null 관련 기능이 언어에 추가되었습니다. F# 형식 모델링에서 | null 사용하는 것은 누락된 정보를 나타내는 idiomatic으로 간주되지 않습니다. 이러한 용도로는 위에서 설명한 대로 옵션을 사용합니다. 스타일 가이드에서 null 관련 규범에 대해 자세히 알아보세요.

조건부 반환 계약

NotNullIfNotNull는 명명된 입력이 null이 아닌 경우 null이 아닌 결과를 약속하는 기존 .NET nullable-analysis 계약입니다.

F# 11부터 null 검사는 주석이 추가된 API를 호출할 때 이 반환 계약을 사용합니다.

open System.IO

let fileName: string = Path.GetFileName("reports/annual.csv")
let extension: string = Path.GetExtension(fileName)
printn (extension.ToUpperInvariant())
// .CSV

let fileNameOf (path: string | null) : string | null =
    Path.GetFileName path

또는 .를 사용하여 <Nullable>enable</Nullable>--checknulls+null 검사를 사용하도록 설정합니다. 참조 어셈블리에는 주석이 포함되어야 합니다. 이 특성은 반환 계약에 적용되며 입력 매개 변수의 이름을 지정합니다. 런타임 null 검사가 아닙니다.

fileName에는 fileNameOf 형식string이 있습니다. 수락하고 반환합니다string | null. 명명된 인수와 첫 번째가 아닌 매개 변수는 지원되지만 여러 조건부 특성이 일반 계약으로 결합되지는 않습니다.

제한되지 않은 nullable 제네릭 interop

제약 T?이 없는 C# API를 구현하려면 FSharp.Core 11에서 다음을 추가합니다 Unchecked.withNull.

let nullableResult (value: 'T) : 'T | null =
    Unchecked.withNull value

제한되는 withNull것과 달리 이 도우미는 모든 'T것을 허용합니다. 값이나 안전성이 아닌 정적 형식만 역참조로 변경합니다.

참조

  • 값
  • 일치 식