F# 6의 새로운 기능

F# 6에는 F# 언어 및 F# 대화형에 몇 가지 개선 사항이 추가되었습니다. .NET 6과 함께 릴리스됩니다.

.NET 다운로드 페이지에서 최신 .NET SDK를 다운로드할 수 있습니다.

시작하기

F# 6은 모든 .NET Core 배포 및 Visual Studio 도구에서 사용할 수 있습니다. 자세한 내용은 F#으로 시작하기를 참조하세요.

작업 {...}

F# 6에는 F# 코드에서 .NET 작업을 작성하기 위한 기본 지원이 포함되어 있습니다. 예를 들어 다음 F# 코드를 사용하여 . NET 호환 작업:

let readFilesTask (path1, path2) =
   async {
        let! bytes1 = File.ReadAllBytesAsync(path1) |> Async.AwaitTask
        let! bytes2 = File.ReadAllBytesAsync(path2) |> Async.AwaitTask
        return Array.append bytes1 bytes2
   } |> Async.StartAsTask

F# 6을 사용하여 이 코드를 다음과 같이 다시 작성할 수 있습니다.

let readFilesTask (path1, path2) =
   task {
        let! bytes1 = File.ReadAllBytesAsync(path1)
        let! bytes2 = File.ReadAllBytesAsync(path2)
        return Array.append bytes1 bytes2
   }

작업 지원은 우수한 TaskBuilder.fs 및 Ply 라이브러리를 통해 F# 5에 사용할 수 있었습니다. 코드를 기본 제공 지원으로 마이그레이션하는 것은 간단해야 합니다. 그러나 몇 가지 차이점이 있습니다. 네임스페이스와 형식 유추는 기본 제공 지원과 이러한 라이브러리 간에 약간 다르며 일부 추가 형식 주석이 필요할 수 있습니다. 필요한 경우 명시적으로 참조하고 각 파일에서 올바른 네임스페이스를 여는 경우 F# 6에서 이러한 커뮤니티 라이브러리를 계속 사용할 수 있습니다.

사용 task {…} 은 사용과 매우 유사합니다 async {…}. 사용 task {…} 은 다음과 같은 async {…}몇 가지 장점이 있습니다.

  • 오버헤드 task {...} 가 낮아 비동기 작업이 신속하게 실행되는 핫 코드 경로의 성능이 향상됩니다.
  • 디버깅 단계 및 스택 추적이 task {…} 더 좋습니다.
  • 작업을 예상하거나 생성하는 .NET 패키지와 상호 운용하는 것이 더 쉽습니다.

async {…}알고 있는 경우 다음과 같은 몇 가지 차이점을 알아야 합니다.

  • task {…} 는 작업을 첫 번째 대기 지점으로 즉시 실행합니다.
  • task {…} 는 취소 토큰을 암시적으로 전파하지 않습니다.
  • task {…}는 암시적 취소 검사 수행하지 않습니다.
  • task {…} 는 비동기 tailcall을 지원하지 않습니다. 즉, 재귀적으로 사용하면 return! .. 중간 비동기 대기가 없는 경우 스택 오버플로가 발생할 수 있습니다.

일반적으로 작업을 사용하는 .NET 라이브러리와 상호 운용하고 비동기 코드 tailcall 또는 암시적 취소 토큰 전파에 의존하지 않는 경우 새 코드에서 이상 async {…} 사용을 task {…} 고려해야 합니다. 기존 코드에서는 코드를 검토한 후에만 전환 task {…} 하여 이전에 멘션 특성에 의존하지 않도록 해야 합니다async {…}.

이 기능은 F# RFC FS-1097을 구현합니다.

를 사용하여 더 간단한 인덱싱 구문 expr[idx]

F# 6에서는 컬렉션을 인덱싱하고 조각화하기 위한 구문을 expr[idx] 사용할 수 있습니다.

F# 5까지 F#은 인덱싱 구문으로 사용 expr.[idx] 되었습니다. 사용 expr[idx] 허용은 F#을 학습하거나 F#을 처음 보는 사람들의 반복된 피드백을 기반으로 하며, 표준 업계 관행과 불필요한 차이로 점 표기법 인덱싱의 사용이 발생합니다.

기본적으로 사용 시 경고가 내보내지지 않으므로 호환성이 손상되는 expr.[idx]변경은 아닙니다. 그러나 코드 설명을 제안하는 일부 정보 메시지는 내보내집니다. 필요에 따라 추가 정보 메시지도 활성화할 수 있습니다. 예를 들어 선택적 정보 경고(/warnon:3566)를 활성화하여 표기법 사용을 expr.[idx] 보고할 수 있습니다. 자세한 내용은 인덱서 표기법을 참조 하세요.

새 코드에서는 인덱싱 구문으로 체계적으로 사용하는 expr[idx] 것이 좋습니다.

이 기능은 F# RFC FS-1110을 구현 합니다.

부분 활성 패턴에 대한 구조체 표현

F# 6은 부분 활성 패턴에 대한 선택적 구조체 표현으로 "활성 패턴" 기능을 보강합니다. 이렇게 하면 특성을 사용하여 부분 활성 패턴을 제한하여 값 옵션을 반환할 수 있습니다.

[<return: Struct>]
let (|Int|_|) str =
   match System.Int32.TryParse(str) with
   | true, int -> ValueSome(int)
   | _ -> ValueNone

특성을 사용해야 합니다. 사용 사이트에서 코드는 변경되지 않습니다. 결과적으로 할당이 줄어듭니다.

이 기능은 F# RFC FS-1039를 구현 합니다.

계산 식에서 오버로드된 사용자 지정 작업

F# 6을 사용하면 오버로드된 메서드에서 CustomOperationAttribute를 사용할 수 있습니다.

계산 식 작성 content기를 다음과 같이 사용하는 것이 좋습니다.

let mem = new System.IO.MemoryStream("Stream"B)
let content = ContentBuilder()
let ceResult =
    content {
        body "Name"
        body (ArraySegment<_>("Email"B, 0, 5))
        body "Password"B 2 4
        body "BYTES"B
        body mem
        body "Description" "of" "content"
    }

body 여기서 사용자 지정 작업은 다양한 형식의 다양한 인수를 사용합니다. 이는 오버로드를 사용하는 다음 작성기의 구현에서 지원됩니다.

type Content = ArraySegment<byte> list

type ContentBuilder() =
    member _.Run(c: Content) =
        let crlf = "\r\n"B
        [|for part in List.rev c do
            yield! part.Array[part.Offset..(part.Count+part.Offset-1)]
            yield! crlf |]

    member _.Yield(_) = []

    [<CustomOperation("body")>]
    member _.Body(c: Content, segment: ArraySegment<byte>) =
        segment::c

    [<CustomOperation("body")>]
    member _.Body(c: Content, bytes: byte[]) =
        ArraySegment<byte>(bytes, 0, bytes.Length)::c

    [<CustomOperation("body")>]
    member _.Body(c: Content, bytes: byte[], offset, count) =
        ArraySegment<byte>(bytes, offset, count)::c

    [<CustomOperation("body")>]
    member _.Body(c: Content, content: System.IO.Stream) =
        let mem = new System.IO.MemoryStream()
        content.CopyTo(mem)
        let bytes = mem.ToArray()
        ArraySegment<byte>(bytes, 0, bytes.Length)::c

    [<CustomOperation("body")>]
    member _.Body(c: Content, [<ParamArray>] contents: string[]) =
        List.rev [for c in contents -> let b = Text.Encoding.ASCII.GetBytes c in ArraySegment<_>(b,0,b.Length)] @ c

이 기능은 F# RFC FS-1056을 구현합니다.

"as" 패턴

F# 6에서는 이제 패턴의 as 오른쪽 자체가 패턴이 될 수 있습니다. 이는 형식 테스트가 입력에 더 강력한 형식을 부여한 경우에 중요합니다. 예를 들어, 다음 코드를 고려하세요.

type Pair = Pair of int * int

let analyzeObject (input: obj) =
    match input with
    | :? (int * int) as (x, y) -> printfn $"A tuple: {x}, {y}"
    | :? Pair as Pair (x, y) -> printfn $"A DU: {x}, {y}"
    | _ -> printfn "Nope"

let input = box (1, 2)

각 패턴 사례에서 입력 개체는 형식 테스트됩니다. 이제 패턴의 오른쪽이 더 강력한 형식의 as 개체와 일치할 수 있는 추가 패턴이 될 수 있습니다.

이 기능은 F# RFC FS-1105를 구현합니다.

들여쓰기 구문 수정 버전

F# 6은 들여쓰기 인식 구문의 사용에서 여러 가지 불일치 및 제한 사항을 제거합니다. RFC FS-1108을 참조하세요. 이렇게 하면 F# 4.0 이후 F# 사용자가 강조 표시한 10개의 중요한 문제가 해결됩니다.

예를 들어 F# 5에서는 다음 코드가 허용되었습니다.

let c = (
    printfn "aaaa"
    printfn "bbbb"
)

그러나 다음 코드는 허용되지 않습니다(경고를 생성).

let c = [
    1
    2
]

F# 6에서는 둘 다 허용됩니다. 이렇게 하면 F#을 더 간단하고 쉽게 배울 수 있습니다. F# 커뮤니티 기여자 Hadrian Tang은 이 기능에 대한 놀랍고 매우 가치있는 체계적인 테스트를 포함하여 이를 주도했습니다.

이 기능은 F# RFC FS-1108을 구현합니다.

추가 암시적 변환

F# 6에서는 RFC FS-1093에 설명된 대로 추가 "암시적" 및 "형식 지정" 변환에 대한 지원을 활성화했습니다.

이 변경은 다음 세 가지 이점을 제공합니다.

  1. 더 적은 명시적 업캐스트가 필요합니다.
  2. 더 적은 명시적 정수 변환이 필요합니다.
  3. 에 대한 일류 지원 NET 스타일 암시적 변환이 추가됨

이 기능은 F# RFC FS-1093을 구현합니다.

추가 암시적 업캐스트 변환

F# 6은 추가 암시적 업캐스트 변환을 구현합니다. 예를 들어 F# 5 및 이전 버전에서는 형식 주석이 있는 경우에도 식에 다른 하위 형식이 있는 함수를 구현할 때 반환 식에 업캐스트가 필요했습니다. 다음 F# 5 코드를 고려합니다.

open System
open System.IO

let findInputSource () : TextReader =
    if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
        // On Monday a TextReader
        Console.In
    else
        // On other days a StreamReader
        File.OpenText("path.txt") :> TextReader

여기서 조건부 컴퓨팅의 분기는 각각 A TextReaderStreamReader 각 분기를 추가하여 두 분기가 StreamReader 형식을 가지도록 했습니다. F# 6에서는 이러한 업캐스트가 자동으로 추가됩니다. 즉, 코드가 더 간단합니다.

let findInputSource () : TextReader =
    if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
        // On Monday a TextReader
        Console.In
    else
        // On other days a StreamReader
        File.OpenText("path.txt")

암시적 변환에 대한 선택적 경고 /warnon:3388 에 설명된 대로 추가 암시적 업캐스트가 사용되는 모든 지점에서 경고를 표시하도록 경고를 선택적으로 사용하도록 설정할 수 있습니다.

암시적 정수 변환

F# 6에서는 두 형식이 모두 알려진 경우 32비트 정수가 64비트 정수로 확장됩니다. 예를 들어 일반적인 API 셰이프를 고려합니다.

type Tensor(…) =
    static member Create(sizes: seq<int64>) = Tensor(…)

F# 5에서는 int64의 정수 리터럴을 사용해야 합니다.

Tensor.Create([100L; 10L; 10L])

또는

Tensor.Create([int64 100; int64 10; int64 10])

F# 6에서는 형식 유추 중에 원본 형식과 double대상 형식을 모두 알 수 있는 경우 확대가 자동으로 nativeintint64int32int32 수행됩니다.int32 따라서 이전 예제 int32 와 같은 경우 리터럴을 사용할 수 있습니다.

Tensor.Create([100; 10; 10])

이러한 변경에도 불구하고 F#은 대부분의 경우 숫자 형식의 명시적 확대를 계속 사용합니다. 예를 들어 암시적 확대는 원본 또는 int16float32float64대상 형식을 알 수 없는 경우와 같은 int8 다른 숫자 형식에 적용되지 않습니다. 암시적 변환에 대한 선택적 경고 /warnon:3389 에 설명된 대로 암시적 숫자 확대가 사용되는 모든 지점에서 경고를 표시하도록 경고를 선택적으로 사용하도록 설정할 수도 있습니다.

에 대한 일류 지원 NET 스타일 암시적 변환

F# 6에서는 메서드를 호출할 때 .NET "op_Implicit" 변환이 F# 코드에 자동으로 적용됩니다. 예를 들어 F# 5에서는 XML용 .NET API를 사용할 때 사용해야 XName.op_Implicit 했습니다.

open System.Xml.Linq
let purchaseOrder = XElement.Load("PurchaseOrder.xml")
let partNos = purchaseOrder.Descendants(XName.op_Implicit "Item")

F# 6 op_Implicit 에서는 원본 식 및 대상 형식에 형식을 사용할 수 있는 경우 인수 식에 변환이 자동으로 적용됩니다.

open System.Xml.Linq
let purchaseOrder = XElement.Load("PurchaseOrder.xml")
let partNos = purchaseOrder.Descendants("Item")

암시적 변환에 대한 선택적 경고 /warnon:3395 에 설명된 대로 메서드 인수에서 확장이 사용되는 모든 지점에서 op_Implicit 경고를 표시하도록 경고를 선택적으로 사용하도록 설정할 수 있습니다.

참고 항목

F# 6의 첫 번째 릴리스에서 이 경고 번호는 /warnon:3390. 충돌로 인해 경고 번호는 나중에 .로 /warnon:3395업데이트되었습니다.

암시적 변환에 대한 선택적 경고

형식 지향 및 암시적 변환은 형식 유추와 제대로 상호 작용하지 않을 수 있으며 이해하기 어려운 코드로 이어질 수 있습니다. 이러한 이유로 이 기능이 F# 코드에서 남용되지 않도록 하기 위한 몇 가지 완화 방법이 있습니다. 첫째, 원본 형식과 대상 형식을 모두 명확하게 알고 있어야 하며 모호성 또는 추가 형식 유추가 발생하지 않아야 합니다. 둘째, 암시적 변환의 사용을 보고하도록 옵트인 경고를 활성화할 수 있으며 기본적으로 경고가 하나 있습니다.

  • /warnon:3388 (추가 암시적 업캐스트)
  • /warnon:3389 (암시적 숫자 확대)
  • /warnon:3391 (기본적으로 메서드가 아닌 인수에서 op_Implicit)
  • /warnon:3395 (메서드 인수에서 op_Implicit)

팀에서 암시적 변환/warnaserror:3388의 모든 사용을 금지하려는 경우 , /warnaserror:3389/warnaserror:3391/warnaserror:3395.

이진 번호 서식 지정

F# 6은 %B 이진 번호 형식에 사용 가능한 형식 지정자에 패턴을 추가합니다. 다음 F# 코드를 고려합니다.

printf "%o" 123
printf "%B" 123

이 코드는 다음 출력을 출력합니다.

173
1111011

이 기능은 F# RFC FS-1100을 구현 합니다.

바인딩 사용 카드

F# 6을 _ 사용하면 바인딩에 use 사용할 수 있습니다. 예를 들면 다음과 같습니다.

let doSomething () =
    use _ = System.IO.File.OpenText("input.txt")
    printfn "reading the file"

이 기능은 F# RFC FS-1102를 구현합니다.

InlineIfLambda

F# 컴파일러에는 코드 인라인을 수행하는 최적화 프로그램이 포함되어 있습니다. F# 6에서는 인수가 람다 함수로 결정되면 해당 인수 자체가 항상 호출 사이트에서 인라인 처리되어야 함을 코드에서 선택적으로 나타낼 수 있는 새로운 선언적 기능을 추가했습니다.

예를 들어 다음 iterateTwice 함수를 사용하여 배열을 트래버스하는 것이 좋습니다.

let inline iterateTwice ([<InlineIfLambda>] action) (array: 'T[]) =
    for j = 0 to array.Length-1 do
        action array[j]
    for j = 0 to array.Length-1 do
        action array[j]

호출 사이트가 다음과 같은 경우:

let arr = [| 1.. 100 |]
let mutable sum = 0
arr  |> iterateTwice (fun x ->
    sum <- sum + x)

그런 다음 인라인 및 기타 최적화 후에 코드가 다음과 같이 됩니다.

let arr = [| 1.. 100 |]
let mutable sum = 0
for j = 0 to arr.Length-1 do
    sum <- sum + arr[j]
for j = 0 to arr.Length-1 do
    sum <- sum + arr[j]

이전 버전의 F#와 달리 이 최적화는 관련된 람다 식의 크기에 관계없이 적용됩니다. 이 기능을 사용하여 루프 언롤링 및 유사한 변환을 보다 안정적으로 구현할 수도 있습니다.

인수가 호출 사이트의 람다 식에 바인딩되지 않는 코드 InlineIfLambda 의 위치를 나타내기 위해 옵트인 경고(/warnon:3517기본적으로 꺼짐)를 설정할 수 있습니다. 일반적인 경우에는 이 경고를 사용하도록 설정하면 안 됩니다. 그러나 특정 종류의 고성능 프로그래밍에서는 모든 코드가 인라인화되고 평면화되도록 하는 것이 유용할 수 있습니다.

이 기능은 F# RFC FS-1098을 구현합니다.

다시 열 수 있는 코드

F# 6의 지원은 task {…} 다시 실행 가능한 코드RFC FS-1087이라는 기초를 기반으로 합니다. 다시 시작 가능한 코드는 다양한 종류의 고성능 비동기 및 생성 상태 컴퓨터를 빌드하는 데 사용할 수 있는 기술 기능입니다.

추가 컬렉션 함수

FSharp.Core 6.0.0은 핵심 컬렉션 함수에 5개의 새 작업을 추가합니다. 이러한 함수는 다음과 같습니다.

  • List/Array/Seq.insertAt
  • List/Array/Seq.removeAt
  • List/Array/Seq.updateAt
  • List/Array/Seq.insertManyAt
  • List/Array/Seq.removeManyAt

이러한 함수는 모두 해당 컬렉션 형식 또는 시퀀스에 대해 복사 및 업데이트 작업을 수행합니다. 이 유형의 작업은 "기능 업데이트"의 한 형태입니다. 이러한 함수를 사용하는 예제는 해당 설명서(예 : List.insertAt)를 참조하세요.

예를 들어 Elmish 스타일로 작성된 간단한 "Todo List" 애플리케이션에 대한 모델, 메시지 및 업데이트 논리를 고려합니다. 여기서 사용자는 애플리케이션과 상호 작용하여 메시지를 생성하고 함수는 update 이러한 메시지를 처리하여 새 모델을 생성합니다.

type Model =
    { ToDo: string list }

type Message =
    | InsertToDo of index: int * what: string
    | RemoveToDo of index: int
    | LoadedToDos of index: int * what: string list

let update (model: Model) (message: Message) =
    match message with
    | InsertToDo (index, what) ->
        { model with ToDo = model.ToDo |> List.insertAt index what }
    | RemoveToDo index ->
        { model with ToDo = model.ToDo |> List.removeAt index }
    | LoadedToDos (index, what) ->
        { model with ToDo = model.ToDo |> List.insertManyAt index what }

이러한 새 함수를 사용하면 논리가 명확하고 간단하며 변경할 수 없는 데이터에만 의존합니다.

이 기능은 F# RFC FS-1113을 구현합니다.

지도에 키 및 값이 있습니다.

FSharp.Core 6.0.0 Map 에서 이 형식은 이제 키 속성을 지원합니다. 이러한 속성은 기본 컬렉션을 복사하지 않습니다.

이 기능은 F# RFC FS-1113에 설명되어 있습니다.

NativePtr에 대한 추가 내장 함수

FSharp.Core 6.0.0은 NativePtr 모듈에 새 내장 함수를 추가합니다.

  • NativePtr.nullPtr
  • NativePtr.isNullPtr
  • NativePtr.initBlock
  • NativePtr.clear
  • NativePtr.copy
  • NativePtr.copyBlock
  • NativePtr.ofILSigPtr
  • NativePtr.toILSigPtr

다른 함수 NativePtr와 마찬가지로 이러한 함수는 인라인 처리되고 사용되지 않는 한 /nowarn:9 경고를 내보낸다. 이러한 함수의 사용은 관리되지 않는 형식으로 제한됩니다.

이 기능은 F# RFC FS-1109설명되어 있습니다.

단위 주석이 있는 추가 숫자 형식

F# 6에서 다음 형식 또는 형식 약어 별칭은 이제 측정 단위 주석을 지원합니다. 새로 추가된 항목은 굵게 표시됩니다.

F# 별칭 CLR 형식
float32/single System.Single
float/double System.Double
decimal System.Decimal
sbyte/int8 System.SByte
int16 System.Int16
int/int32 System.Int32
int64 System.Int64
byte/uint8 System.Byte
uint16 System.UInt16
uint/uint32 System.UInt32
uint64 System.UIn64
nativeint System.IntPtr
unativeint System.UIntPtr

예를 들어 다음과 같이 부호 없는 정수에 주석을 달 수 있습니다.

[<Measure>]
type days

let better_age = 3u<days>

이 기능은 F# RFC FS-1091에 설명되어 있습니다.

거의 사용되지 않는 기호 연산자 정보 경고

F# 6에서는 F# 6 이상에서 , !incrdecr 그 이상의 사용을 :=정규화 해제하는 소프트 지침을 추가합니다. 이러한 연산자와 함수를 사용하면 코드를 속성의 Value 명시적 사용으로 바꾸라는 정보 메시지를 생성합니다.

F# 프로그래밍에서는 힙 할당 변경 가능 레지스터에 참조 셀을 사용할 수 있습니다. 때때로 유용하지만 대신 사용할 수 있기 때문에 let mutable 최신 F# 코딩에는 거의 필요하지 않습니다. F# 코어 라이브러리에는 두 개의 연산 := 자와 ! 두 개의 함수가 incr 포함되며 특히 참조 호출과 decr 관련이 있습니다. 이러한 연산자가 있으면 참조 셀이 필요한 것보다 F# 프로그래밍의 중심이 되므로 모든 F# 프로그래머가 이러한 연산자를 알아야 합니다. 또한 연산자는 ! 코드를 번역할 때 잠재적으로 미묘한 버그 소스인 C# 및 기타 언어의 작업과 not 쉽게 혼동될 수 있습니다.

이 변경의 근거는 F# 프로그래머가 알아야 하는 연산자 수를 줄여 초보자를 위한 F#을 간소화하는 것입니다.

예를 들어 다음 F# 5 코드를 고려합니다.

let r = ref 0

let doSomething() =
    printfn "doing something"
    r := !r + 1

첫째, 참조 셀은 일반적으로 대신 사용할 수 있으므로 let mutable 최신 F# 코딩에서 거의 필요하지 않습니다.

let mutable r = 0

let doSomething() =
    printfn "doing something"
    r <- r + 1

참조 셀을 사용하는 경우 F# 6은 마지막 줄을 r.Value <- r.Value + 1로 변경하라는 정보 경고를 내보내고 참조 셀의 적절한 사용에 대한 추가 지침에 연결합니다.

let r = ref 0

let doSomething() =
    printfn "doing something"
    r.Value <- r.Value + 1

이러한 메시지는 경고가 아닙니다. IDE 및 컴파일러 출력에 표시된 "정보 메시지"입니다. F# re기본s 이전 버전과 호환됩니다.

이 기능은 F# RFC FS-1111을 구현합니다.

F# 도구: Visual Studio에서 스크립팅의 기본값인 .NET 6

Visual Studio에서 F# 스크립트(.fsx)를 열거나 실행하는 경우 기본적으로 스크립트는 64비트 실행과 함께 .NET 6을 사용하여 분석되고 실행됩니다. 이 기능은 Visual Studio 2019의 이후 릴리스에서 미리 보기로 제공되며 이제 기본적으로 사용하도록 설정됩니다.

.NET Framework 스크립팅을 사용하도록 설정하려면 도구>옵션>F# 도구>F# 대화형을 선택합니다. .NET Core 스크립팅 사용을 false설정한 다음 F# 대화형 창을 다시 시작합니다. 이 설정은 스크립트 편집 및 스크립트 실행 모두에 영향을 줍니다. .NET Framework 스크립팅에 32비트 실행을 사용하도록 설정하려면 64비트 F# Interactive도 false설정합니다. .NET Core 스크립팅에는 32비트 옵션이 없습니다.

F# 도구: F# 스크립트의 SDK 버전 고정

.NET SDK 설정이 있는 global.json 파일이 포함된 디렉터리에서 스크립트를 실행하는 dotnet fsi 경우 나열된 버전의 .NET SDK가 스크립트를 실행하고 편집하는 데 사용됩니다. 이 기능은 이후 버전의 F# 5에서 사용할 수 있습니다.

예를 들어 디렉터리에 .NET SDK 버전 정책을 지정하는 다음 global.json 파일이 있는 스크립트가 있다고 가정합니다.

{
  "sdk": {
    "version": "5.0.200",
    "rollForward": "minor"
  }
}

이제 이 디렉터리에서 스크립트를 사용하여 dotnet fsi실행하는 경우 SDK 버전이 적용됩니다. 스크립트를 컴파일, 분석 및 실행하는 데 사용되는 SDK를 "잠글" 수 있는 강력한 기능입니다.

Visual Studio 및 기타 IDE에서 스크립트를 열고 편집하는 경우 도구는 스크립트를 분석하고 검사 때 이 설정을 적용합니다. SDK를 찾을 수 없는 경우 개발 머신에 설치해야 합니다.

Linux 및 기타 Unix 시스템에서는 이를 shebang결합하여 스크립트를 직접 실행하기 위한 언어 버전도 지정할 수 있습니다. 간단한 세방은 다음과 같습니다.script.fsx

#!/usr/bin/env -S dotnet fsi

printfn "Hello, world"

이제 스크립트를 .을 script.fsx사용하여 직접 실행할 수 있습니다. 다음과 같이 기본이 아닌 특정 언어 버전과 결합할 수 있습니다.

#!/usr/bin/env -S dotnet fsi --langversion:5.0

참고 항목

이 설정은 최신 언어 버전으로 가정하여 스크립트를 분석하는 편집 도구에서 무시됩니다.

레거시 기능 제거

F# 2.0 이후 사용되지 않는 일부 레거시 기능에는 오랫동안 경고가 있습니다. F# 6에서 이러한 기능을 사용하면 명시적으로 사용하지 /langversion:5.0않는 한 오류가 발생합니다. 오류를 제공하는 기능은 다음과 같습니다.

  • 예를 들어 (int, int) Dictionary, 접두사 형식 이름을 사용하는 여러 제네릭 매개 변수입니다. F# 6에서 오류가 발생합니다. 대신 표준 구문을 Dictionary<int,int> 사용해야 합니다.
  • #indent "off". 이 오류는 오류가 됩니다.
  • x.(expr). 이 오류는 오류가 됩니다.
  • module M = struct … end . 이 오류는 오류가 됩니다.
  • 입력 및 *.mli.*.ml 이 오류는 오류가 됩니다.
  • (*IF-CAML*) 사용 또는 (*IF-OCAML*). 이 오류는 오류가 됩니다.
  • land, lor, lxor, lsllsr또는 asr 접두사 연산자로 사용합니다. 이는 OCaml의 키워드(keyword) 접두사이고 FSharp.Core에 정의되지 않았기 때문에 F#의 접두사 키워드(keyword). 이제 이러한 키워드(keyword) 사용하면 경고가 표시됩니다.

F# RFC FS-1114를 구현합니다.