Nieuw in F# 4.5
F# 4.5 voegt meerdere verbeteringen toe aan de F#-taal. Veel van deze functies zijn samen toegevoegd om u in staat te stellen efficiënte code te schrijven in F# en tegelijkertijd ervoor te zorgen dat deze code veilig is. Dit betekent het toevoegen van enkele concepten aan de taal en een aanzienlijke hoeveelheid compileranalyse bij het gebruik van deze constructies.
Aan de slag
F# 4.5 is beschikbaar in alle .NET Core-distributies en Visual Studio-hulpprogramma's. Ga aan de slag met F# voor meer informatie.
Span- en byref-achtige structs
Met het Span<T> type dat in .NET Core is geïntroduceerd, kunt u buffers in het geheugen weergeven op een sterk getypte manier. Dit is nu toegestaan in F# vanaf F# 4.5. In het volgende voorbeeld ziet u hoe u een functie die op een Span<T> andere bufferweergave werkt, opnieuw kunt gebruiken:
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"
Een belangrijk aspect hiervan is dat Span en andere byref-structs zeer stijve statische analyse hebben uitgevoerd door de compiler die hun gebruik beperken op manieren die u mogelijk onverwacht zult vinden. Dit is de fundamentele afweging tussen prestaties, expressiviteit en veiligheid die wordt geïntroduceerd in F# 4.5.
Vernieuwd doorrefs
Vóór F# 4.5 waren Byrefs in F# onveilig en ondeugdelijk voor talloze toepassingen. Geluidsproblemen rond byrefs zijn opgelost in F# 4.5 en dezelfde statische analyse die is uitgevoerd voor span- en byref-structs zijn ook toegepast.
inref'T<> en outref'T<>
Om het begrip alleen-lezen, alleen-schrijven en beheerde aanwijzer voor lezen/schrijven te vertegenwoordigen, introduceert F# 4.5 de inref<'T>
typen outref<'T>
die respectievelijk alleen-lezen- en alleen-schrijven-aanwijzers vertegenwoordigen. Elk heeft verschillende semantiek. U kunt bijvoorbeeld niet schrijven naar een inref<'T>
:
let f (dt: inref<DateTime>) =
dt <- DateTime.Now // ERROR - cannot write to an inref!
Standaard leidt type deductie ertoe dat beheerde aanwijzers inref<'T>
in overeenstemming zijn met de onveranderbare aard van F#-code, tenzij iets al als veranderlijk is gedeclareerd. Als u iets beschrijfbaar wilt maken, moet u een type declareren als mutable
voordat u het adres doorgeeft aan een functie of lid dat het bewerkt. Zie Byrefs voor meer informatie.
Alleen-lezen structs
Vanaf F# 4.5 kunt u aantekeningen toevoegen aan een struct met IsReadOnlyAttribute als zodanig:
[<IsReadOnly; Struct>]
type S(count1: int, count2: int) =
member x.Count1 = count1
member x.Count2 = count2
Hierdoor kunt u geen onveranderbaar lid in de struct declareren en metagegevens verzenden waarmee F# en C# deze als alleen-lezen kunnen behandelen wanneer ze worden gebruikt vanuit een assembly. Zie ReadOnly-structs voor meer informatie.
Ongeldige aanwijzers
Het voidptr
type wordt toegevoegd aan F# 4.5, net als de volgende functies:
NativePtr.ofVoidPtr
om een ongeldige aanwijzer te converteren naar een systeemeigen aanwijzerNativePtr.toVoidPtr
een systeemeigen aanwijzer converteren naar een ongeldige aanwijzer
Dit is handig bij het samenwerken met een systeemeigen onderdeel dat gebruikmaakt van ongeldige aanwijzers.
Het match!
-trefwoord
Het match!
trefwoord verbetert het patroon dat overeenkomt met het patroon in een berekeningsexpressie:
// 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
}
Hiermee kunt u code verkorten waarbij vaak opties (of andere typen) worden gemengd met rekenexpressies zoals asynchroon. Zie match!voor meer informatie.
Ontspannen upcastingvereisten in matrix-, lijst- en reeksexpressies
Het combineren van typen waarbij men van een ander type in matrix-, lijst- en reeksexpressies kan overnemen, heeft traditioneel vereist dat u elk afgeleid type upcastt naar het bovenliggende type met :>
of upcast
. Dit is nu ontspannen, gedemonstreerd als volgt:
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
Ontspanning van inspringing voor matrix- en lijstexpressies
Vóór F# 4.5 moest u matrix- en lijstexpressies overmatig laten inspringen wanneer deze worden doorgegeven als argumenten voor methode-aanroepen. Dit is niet meer vereist:
module NoExcessiveIndenting =
System.Console.WriteLine(format="{0}", arg = [|
"hello"
|])
System.Console.WriteLine([|
"hello"
|])
Feedback
https://aka.ms/ContentUserFeedback.
Binnenkort: Gedurende 2024 worden GitHub Issues uitgefaseerd als het feedbackmechanisme voor inhoud. Dit wordt vervangen door een nieuw feedbacksysteem. Ga voor meer informatie naar:Feedback verzenden en bekijken voor