F# 4.5'teki yenilikler

F# 4.5, F# diline birden çok geliştirme ekler. Bu özelliklerin çoğu, F# dilinde verimli kod yazmanıza olanak tanımak ve bu kodun güvenli olduğundan emin olmak için bir araya eklendi. Bunu yapmak, bu yapıları kullanırken dile birkaç kavram ve önemli miktarda derleyici analizi eklemek anlamına gelir.

Kullanmaya başlayın

F# 4.5 tüm .NET Core dağıtımlarında ve Visual Studio araçlarında kullanılabilir. Daha fazla bilgi edinmek için F# kullanmaya başlayın.

Span ve byref benzeri yapılar

Span<T>.NET Core'da sunulan tür, bellekteki arabellekleri kesin olarak yazılan bir şekilde temsil etmenizi sağlar. Bu, artık F# 4.5 ile başlayarak F# dilinde izin verilir. Aşağıdaki örnek, farklı arabellek gösterimleriyle üzerinde çalışan bir Span<T> işlevi nasıl yeniden kullanabileceğinizi gösterir:

let safeSum (bytes: Span<byte>) =
    let mutable sum = 0
    for i in 0 .. bytes.Length - 1 do
        sum <- sum + int bytes[i]
    sum

// managed memory
let arrayMemory = Array.zeroCreate<byte>(100)
let arraySpan = new Span<byte>(arrayMemory)

safeSum(arraySpan) |> printfn "res = %d"

// native memory
let nativeMemory = Marshal.AllocHGlobal(100);
let nativeSpan = new Span<byte>(nativeMemory.ToPointer(), 100)

safeSum(nativeSpan) |> printfn "res = %d"
Marshal.FreeHGlobal(nativeMemory)

// stack memory
let mem = NativePtr.stackalloc<byte>(100)
let mem2 = mem |> NativePtr.toVoidPtr
let stackSpan = Span<byte>(mem2, 100)

safeSum(stackSpan) |> printfn "res = %d"

Bunun önemli bir yönü, Span ve diğer byref benzeri yapıların derleyici tarafından gerçekleştirilen ve bunların kullanımını beklenmedik şekilde kısıtlayan çok katı statik analize sahip olmasıdır. Bu, F# 4.5'te sunulan performans, ifade ve güvenlik arasındaki temel dengedir.

Yenilenen byrefs

F# 4.5'in öncesinde, F# dilindeki Byrefs çok sayıda uygulama için güvenli değildi ve uyumlu değildi. Byrefs ile ilgili sağlamlık sorunları F# 4.5'te giderilmiştir ve span ve byref benzeri yapılar için yapılan statik analiz de uygulanmıştır.

inref'T<> ve outref'T<>

Salt okunur, salt yazma ve okuma/yazma yönetilen işaretçisi kavramlarını temsil etmek için, F# 4.5 sırasıyla salt okunur ve salt yazma işaretçilerini temsil eden türleri sunarinref<'T>outref<'T>. Her birinin farklı semantiği vardır. Örneğin, bir inref<'T>öğesine yazamazsınız:

let f (dt: inref<DateTime>) =
    dt <- DateTime.Now // ERROR - cannot write to an inref!

Varsayılan olarak, tür çıkarımı yönetilen işaretçileri F# kodunun sabit doğasına uygun olacak şekilde inref<'T> çıkarsar( bir şey zaten değiştirilebilir olarak bildirilmemişse). Bir şeyi yazılabilir hale getirmek için, adresini onu işleyen bir işleve veya üyeye geçirmeden önce türü olarak mutable bildirmeniz gerekir. Daha fazla bilgi için bkz . Byrefs.

Salt okunur yapılar

F# 4.5'den başlayarak bir yapıya IsReadOnlyAttribute şu şekilde açıklama ekleyebilirsiniz:

[<IsReadOnly; Struct>]
type S(count1: int, count2: int) =
    member x.Count1 = count1
    member x.Count2 = count2

Bu, yapıda değiştirilebilir bir üye bildirmenizi engeller ve bir derlemeden kullanıldığında F# ve C# değerlerinin bunu salt okunur olarak işlemesine olanak tanıyan meta veriler yayar. Daha fazla bilgi edinmek için bkz . ReadOnly yapıları.

Geçersiz işaretçiler

Tür voidptr , aşağıdaki işlevler gibi F# 4.5'e eklenir:

  • NativePtr.ofVoidPtr geçersiz bir işaretçiyi yerel int işaretçisine dönüştürmek için
  • NativePtr.toVoidPtr yerel int işaretçisini geçersiz işaretçiye dönüştürmek için

Bu, void işaretçilerini kullanan yerel bir bileşenle birlikte çalışırken yararlıdır.

match! anahtar sözcüğü

anahtar match! sözcüğü, bir hesaplama ifadesinin içinde desen eşleştirmeyi geliştirir:

// Code that returns an asynchronous option
let checkBananaAsync (s: string) =
    async {
        if s = "banana" then
            return Some s
        else
            return None
    }

// Now you can use 'match!'
let funcWithString (s: string) =
    async {
        match! checkBananaAsync s with
        | Some bananaString -> printfn "It's banana!"
        | None -> printfn "%s" s
}

Bu, genellikle zaman uyumsuz gibi hesaplama ifadeleriyle karıştırma seçeneklerini (veya diğer türleri) içeren kodu kısaltmanıza olanak tanır. Daha fazla bilgi edinmek için bkz . eşleştirme!.

Dizi, liste ve dizi ifadelerinde gevşek yukarı yayın gereksinimleri

Bir türün dizi, liste ve sıra ifadelerinin içinde başka bir türe devralabileceği türleri karıştırmak, geleneksel olarak türetilmiş herhangi bir türü veya upcastile :> üst türüne yükseltmenizi gerektirir. Bu artık gevşetildi ve aşağıdaki gibi gösteriliyor:

let x0 : obj list  = [ "a" ] // ok pre-F# 4.5
let x1 : obj list  = [ "a"; "b" ] // ok pre-F# 4.5
let x2 : obj list  = [ yield "a" :> obj ] // ok pre-F# 4.5

let x3 : obj list  = [ yield "a" ] // Now ok for F# 4.5, and can replace x2

Dizi ve liste ifadeleri için girinti gevşetme

F# 4.5'in öncesinde, yöntem çağrılarına bağımsız değişken olarak geçirildiğinde diziyi ve liste ifadelerini aşırı girintili olarak belirlemeniz gerekiyordu. Bu artık gerekli değildir:

module NoExcessiveIndenting =
    System.Console.WriteLine(format="{0}", arg = [|
        "hello"
    |])
    System.Console.WriteLine([|
        "hello"
    |])