Typrückschluss (F#)
In diesem Thema wird beschrieben, wie der F#-Compiler die Typen von Werten, Variablen, Parametern und Rückgabewerten ableitet.
Typrückschluss im Allgemeinen
Bei Verwendung von Typrückschluss müssen Sie die Typen von F#-Konstrukten nicht angeben, es sei denn, der Compiler kann den Typ nicht schlüssig ableiten. Das Weglassen von expliziten Typinformationen bedeutet nicht, dass F# eine dynamisch typisierte Sprache ist oder dass Werte in F# schwach typisiert sind. F# ist eine statisch typisierte Sprache. Dies bedeutet, dass der Compiler während der Kompilierung den genauen Typ für jedes Konstrukt ableitet. Wenn nicht genügend Informationen zum Ableiten der Typen für die einzelnen Konstrukte durch den Compiler vorhanden sind, müssen Sie zusätzliche Typinformationen bereitstellen, in der Regel durch Hinzufügen von expliziten Typanmerkungen im Code.
Rückschluss von Parameter- und Rückgabetypen
In einer Parameterliste müssen Sie nicht den Typ jedes Parameters angeben. Dennoch ist F# eine statisch typisierte Sprache, daher verfügt jeder Wert und Ausdruck zur Kompilierzeit über einen eindeutigen Typ. Für die Typen, die Sie nicht explizit angeben, leitet der Compiler den Typ anhand des Kontexts per Rückschluss ab. Wenn für den Typ nichts anderes angegeben ist, wird er als generischer Typ abgeleitet. Wenn im Code ein Wert inkonsistent verwendet wird, sodass kein einzelner abgeleiteter Typ jeder Verwendung eines Werts entspricht, gibt der Compiler einen Fehler aus.
Der Rückgabetyp einer Funktion wird anhand des Typs des letzten Ausdrucks in der Funktion bestimmt.
Beispielsweise werden im folgenden Code die Parametertypen a und b sowie der Rückgabetyp als int abgeleitet, da das Literal 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 100 in ein uint32 ändern, indem Sie das Suffix u anfügen, werden die Typen von a, b sowie der Rückgabewert als uint32 abgeleitet.
Sie können den Typrückschluss auch beeinflussen, indem Sie andere Konstrukte verwenden, die Einschränkungen des Typs beinhalten, z. B. Funktionen und Methoden, die nur mit einem bestimmten Typ verwendet werden können.
Sie können auch explizite Typanmerkungen auf Funktions- oder Methodenparameter oder Variablen in Ausdrücken anwenden, wie in den folgenden Beispielen gezeigt. Konflikte zwischen unterschiedlichen Einschränkungen führen zu Fehlern.
// 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 den Rückgabewert einer Funktion explizit angeben, indem Sie nach allen Parametern eine Typanmerkung angeben.
let addu1 x y : uint32 =
x + y
Ein gängiger Fall, bei dem eine Typanmerkung für einen Parameter nützlich ist, ist, 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ängt, betrachtet der Compiler den Parameter als generischen Parameter. Dies wird als automatische Verallgemeinerung bezeichnet, und diese kann das Schreiben von generischem Code erheblich erleichtern, ohne die Komplexität zu erhöhen.
Beispielsweise werden in der folgenden Funktion zwei Parameter eines beliebigen Typs in einem Tupel kombiniert.
let makeTuple a b = (a, b)
Der Typ wird wie folgt abgeleitet:
'a -> 'b -> 'a * 'b
Zusätzliche Informationen
Typrückschluss wird in der F# Language Specification noch genauer beschrieben.