Dela via


Typinferens

Det här avsnittet beskriver hur F#-kompilatorn härleder typerna av värden, variabler, parametrar och returvärden.

Typinferens i Allmänt

Tanken med typinferens är att du inte behöver ange typerna av F#-konstruktioner förutom när kompilatorn inte slutgiltigt kan härleda typen. Om du utelämnar explicit typinformation betyder det inte att F# är ett dynamiskt skrivet språk eller att värdena i F# skrivs svagt. F# är ett statiskt skrivet språk, vilket innebär att kompilatorn härleder en exakt typ för varje konstruktion under kompilering. Om det inte finns tillräckligt med information för kompilatorn för att härleda typerna av varje konstruktion måste du ange ytterligare typinformation, vanligtvis genom att lägga till explicita typanteckningar någonstans i koden.

Slutsatsdragning av parameter- och returtyper

I en parameterlista behöver du inte ange typen av varje parameter. Och ändå är F# ett statiskt skrivet språk, och därför har varje värde och uttryck en bestämd typ vid kompileringstiden. För de typer som du inte uttryckligen anger härleder kompilatorn typen baserat på kontexten. Om typen inte har angetts på annat sätt härleds den till att vara generisk. Om koden använder ett värde inkonsekvent, på ett sådant sätt att det inte finns någon enda härledd typ som uppfyller alla användningsområden för ett värde, rapporterar kompilatorn ett fel.

Returtypen för en funktion bestäms av typen av det sista uttrycket i funktionen.

I följande kod kan till exempel parametertyperna a och returtypen härledas till att bero int på att literalen 100 är av typen intb .

let f a b = a + b + 100

Du kan påverka typinferens genom att ändra literalerna. Om du gör 100 a uint32 genom att lägga till suffixet u, kommer typerna av a, boch returvärdet att härledas uint32till .

Du kan också påverka typinferens genom att använda andra konstruktioner som innebär begränsningar för typen, till exempel funktioner och metoder som endast fungerar med en viss typ.

Du kan också använda explicita typanteckningar för funktions- eller metodparametrar eller variabler i uttryck, som du ser i följande exempel. Fel uppstår om konflikter uppstår mellan olika begränsningar.

// Type annotations on a parameter.
let addu1 (x : uint32) y =
    x + y

// Type annotations on an expression.
let addu2 x y =
    (x : uint32) + y

Du kan också uttryckligen ange returvärdet för en funktion genom att ange en typanteckning efter alla parametrar.

let addu1 x y : uint32 =
   x + y

Ett vanligt fall där en typanteckning är användbar för en parameter är när parametern är en objekttyp och du vill använda en medlem.

let replace(str: string) =
    str.Replace("A", "a")

Automatisk generalisering

Om funktionskoden inte är beroende av typen av en parameter anser kompilatorn att parametern är generisk. Detta kallas automatisk generalisering, och det kan vara ett kraftfullt stöd för att skriva generisk kod utan att öka komplexiteten.

Följande funktion kombinerar till exempel två parametrar av vilken typ som helst till en tupplar.

let makeTuple a b = (a, b)

Typen härleds till att vara

'a -> 'b -> 'a * 'b

Ytterligare Information

Typinferens beskrivs mer detaljerat i F#-språkspecifikationen.

Se även