Typableitung

In diesem Thema wird beschrieben, wie der F#-Compiler Typen von Werten, Variablen, Parametern und Rückgabewerten ableitet.

Typrückschluss im Allgemeinen

Der Grundgedanke hinter dem Typrückschluss ist, dass Sie die Typen von F#-Konstrukten nicht angeben müssen, außer wenn der Compiler den Typ nicht eindeutig ableiten kann. Das Weglassen expliziter Typinformationen bedeutet nicht, dass F# eine dynamisch typisierte Sprache ist oder dass Werte in F# schwach typisiert sind. F# ist eine statisch typisierte Sprache, der Compiler leitet also während der Kompilierung den genauen Typ für jedes Konstrukt her. Wenn der Compiler nicht über ausreichend Informationen verfügt, um die Typen der einzelnen Konstrukte herzuleiten, müssen Sie zusätzliche Typinformationen angeben – in der Regel durch Hinzufügen expliziter Typanmerkungen an einer beliebigen Stelle im Code.

Rückschließen von Parameter- und Rückgabetypen

In einer Parameterliste müssen Sie die Typen der einzelnen Parameter nicht angeben. Dennoch ist F# eine statisch typisierte Sprache, und daher weist jeder Wert und jeder Ausdruck zur Kompilierungszeit einen bestimmten Typ auf. Für diese Typen, die Sie nicht explizit angeben, leitet der Compiler den Typ basierend auf dem Kontext ab. Wenn der Typ nicht anderweitig angegeben ist, ergibt der Rückschluss einen generischen Typ. Wenn der Code einen Wert inkonsistent verwendet, sodass kein einzelner abgeleiteter Typ vorhanden ist, der für alle Verwendungen eines Werts gilt, meldet der Compiler einen Fehler.

Der Rückgabetyp einer Funktion wird durch den Typ des letzten Ausdrucks in der Funktion bestimmt.

Im folgenden Code beispielsweise werden die Parametertypen a und b und der Rückgabetyp als int abgeleitet, da der Literalwert 100 vom Typ int ist.

let f a b = a + b + 100

Sie können den Typrückschluss beeinflussen, indem Sie die Literale ändern. Wenn Sie den Wert 100 zu einem uint32-Wert machen, indem Sie das Suffix u anfügen, werden die Typen von a und b sowie der Rückgabewert als uint32 abgeleitet.

Sie können den Typrückschluss auch beeinflussen, indem Sie andere Konstrukte verwenden, die Einschränkungen auf den Typ anwenden, z. B. Funktionen und Methoden, die nur mit einem bestimmten Typ funktionieren.

Außerdem können Sie explizite Typanmerkungen auf Funktions- oder Methodenparameter oder Variablen in Ausdrücken anwenden, wie in den folgenden Beispielen gezeigt. Bei Konflikten zwischen verschiedenen Einschränkungen treten Fehler auf.

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

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

Sie können auch explizit den Rückgabewert einer Funktion angeben, indem Sie nach allen Parametern eine Typanmerkung eingeben.

let addu1 x y : uint32 =
   x + y

Eine Typanmerkung für einen Parameter ist häufig nützlich, wenn der Parameter ein Objekttyp ist und Sie einen Member verwenden möchten.

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

Automatische Verallgemeinerung

Wenn der Funktionscode nicht vom Typ eines Parameters abhängig ist, betrachtet der Compiler den Parameter als generisch. Dies wird also automatische Generalisierung bezeichnet und kann eine sehr nützliche Hilfe sein, wenn Sie generischen Code schreiben möchten, ohne die Komplexität zu erhöhen.

Die folgende Funktion kombiniert beispielsweise zwei Parameter eines beliebigen Typs in einem Tupel.

let makeTuple a b = (a, b)

Der Typ wird wie folgt abgeleitet:

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

Zusätzliche Informationen

Der Typrückschluss wird in der F#-Sprachspezifikation ausführlicher beschrieben.

Siehe auch