Ich sehe, dass es bereits einige gute Antworten gibt. Einige davon wiederhole ich, aber manchmal möchten Sie die Dinge einfach in Ihre eigenen Worte fassen. Ich werde einige Beispiele aus C ++ kommentieren, da dies die Sprache ist, mit der ich am vertrautesten bin.
Was notwendig ist, ist niemals unklug. Typinferenz ist notwendig, um andere Sprachfunktionen praktisch zu machen. In C ++ ist es möglich, unaussprechbare Typen zu haben.
struct {
double x, y;
} p0 = { 0.0, 0.0 };
// there is no name for the type of p0
auto p1 = p0;
C ++ 11 fügte Lambdas hinzu, die auch nicht ausgesprochen werden können.
auto sq = [](int x) {
return x * x;
};
// there is no name for the type of sq
Typinferenz untermauert auch Vorlagen.
template <class x_t>
auto sq(x_t const& x)
{
return x * x;
}
// x_t is not known until it is inferred from an expression
sq(2); // x_t is int
sq(2.0); // x_t is double
Aber Ihre Fragen lauteten: "Warum sollte ich als Programmierer den Typ meiner Variablen ableiten wollen, wenn ich den Code lese? Ist es nicht schneller für jemanden, nur den Typ zu lesen, als zu überlegen, welcher Typ vorhanden ist?"
Typinferenz beseitigt Redundanz. Wenn es darum geht, Code zu lesen, kann es manchmal schneller und einfacher sein, redundante Informationen im Code zu haben, aber Redundanz kann die nützlichen Informationen überschatten . Beispielsweise:
std::vector<int> v;
std::vector<int>::iterator i = v.begin();
Ein C ++ - Programmierer ist mit der Standardbibliothek nur wenig vertraut, um zu erkennen, dass es sich bei i um einen Iterator handelt, i = v.begin()
sodass die explizite Typdeklaration nur einen begrenzten Wert hat. Durch sein Vorhandensein verdeckt es wichtigere Details (wie das, das i
auf den Anfang des Vektors zeigt). Die feine Antwort von @amon liefert ein noch besseres Beispiel für die Ausführlichkeit, die wichtige Details in den Schatten stellt. Im Gegensatz dazu werden bei der Verwendung von Typinferenz die wichtigen Details stärker hervorgehoben.
std::vector<int> v;
auto i = v.begin();
Obwohl das Lesen von Code wichtig ist, reicht es nicht aus. Irgendwann müssen Sie aufhören zu lesen und mit dem Schreiben von neuem Code beginnen. Redundanz im Code macht das Ändern von Code langsamer und schwieriger. Angenommen, ich habe das folgende Codefragment:
std::vector<int> v;
std::vector<int>::iterator i = v.begin();
In dem Fall, dass ich den Werttyp des Vektors ändern muss, um den Code zu verdoppeln, in:
std::vector<double> v;
std::vector<double>::iterator i = v.begin();
In diesem Fall muss ich den Code an zwei Stellen ändern. Vergleichen Sie die Typinferenz mit dem Originalcode:
std::vector<int> v;
auto i = v.begin();
Und der geänderte Code:
std::vector<double> v;
auto i = v.begin();
Beachten Sie, dass ich nur noch eine Codezeile ändern muss. Wenn Sie dies auf ein großes Programm extrapolieren, kann die Typinferenz Änderungen an Typen viel schneller verbreiten als mit einem Editor.
Redundanz im Code schafft die Möglichkeit von Fehlern. Immer wenn Ihr Code davon abhängig ist, dass zwei Informationen gleichwertig sind, besteht die Möglichkeit eines Fehlers. Beispielsweise gibt es eine Inkonsistenz zwischen den beiden Typen in dieser Anweisung, die wahrscheinlich nicht beabsichtigt ist:
int pi = 3.14159;
Redundanz erschwert das Erkennen von Absichten. In einigen Fällen kann die Typinferenz einfacher zu lesen und zu verstehen sein, da sie einfacher ist als die explizite Typspezifikation. Betrachten Sie das Codefragment:
int y = sq(x);
In dem Fall, dass sq(x)
ein zurückgegeben wird int
, ist es nicht offensichtlich, ob y
es sich um einen int
Rückgabetyp handelt sq(x)
oder ob er zu den verwendeten Anweisungen passt y
. Wenn ich anderen Code so ändere, dass er sq(x)
nicht mehr zurückgegeben wird int
, ist allein aus dieser Zeile nicht ersichtlich, ob der Typ von y
aktualisiert werden soll. Vergleichen Sie den gleichen Code, verwenden Sie jedoch die Typinferenz:
auto y = sq(x);
In diesem ist die Absicht klar, y
muss der gleiche Typ sein, wie von zurückgegeben sq(x)
. Wenn der Code den Rückgabetyp sq(x)
von y
ändert, wird der Änderungstyp automatisch angepasst.
In C ++ gibt es einen zweiten Grund, warum das obige Beispiel mit der Typinferenz einfacher ist. Die Typinferenz kann keine implizite Typkonvertierung einführen. Wenn der Rückgabetyp sq(x)
nicht ist int
, fügt der Compiler stillschweigend eine implizite Konvertierung in ein int
. Wenn der Rückgabetyp von sq(x)
ein Typ komplexer Typ ist, der definiert operator int()
, kann dieser verborgene Funktionsaufruf beliebig komplex sein.