Hier ist ein einfaches Perl, um zu zählen, wie oft ein Wert in einem Array auftritt. Dies läuft ohne Warnungen.
%Vor%Wenn der Schleifenkörper zu
geändert wird %Vor%Perl warnt "Verwendung von nicht initialisierten Werten zusätzlich".
Was passiert unter der Motorhaube? Warum wird der Wert initialisiert, wenn er als Operand für den Operator ++ und nicht initialisiert mit dem Operator + übergeben wird?
Der Operator + wertet sowohl die Form links als auch die Form rechts davon aus und gibt dann die Summe beider Werte zurück. Die Hash-Aufruf-Auswertung sieht keinen speziellen Kontext.
Der ++ Operator hat eine spezielle Magie eingebaut. Zitat aus der perlop-Manpage bezüglich des ++ Operators:
"undef" wird immer als numerisch behandelt und insbesondere vor dem Inkrementieren in "0" geändert (so dass ein Post-Inkrement eines undef-Werts 0 anstatt "undef" zurückgibt).
edit : Um den Unterschied zu verdeutlichen, ändert ++ den Wert an Ort und Stelle, während + nur seine Argumente als Eingabe nimmt. Wenn + einen undefinierten Wert sieht, ist normalerweise etwas falsch gelaufen, aber für ++ ist das Beispiel für die Hash-Manipulation sehr typisch - der Benutzer möchte undef als 0 behandeln, anstatt jedes Mal prüfen und initialisieren zu müssen. Es scheint also sinnvoll, diese Operatoren auf diese Weise zu behandeln.
Es ist nicht so, dass Perl notwendigerweise Werte initialisiert, aber dass es nicht immer vor ihnen warnt. Versuchen Sie nicht, über eine Regel nachzudenken, denn Sie werden immer Ausnahmen finden, und wenn Sie denken, dass Sie es herausgefunden haben, wird die nächste Version von Perl die Warnungen auf Sie ändern.
In diesem Fall, wie Harleqin sagte, haben die automatischen Inkrementoperatoren einen Sonderfall.
Bestimmte Benutzer verzichten bewusst auf die Warnung "nicht initialisiert" weil sie häufig in Situationen verwendet werden, in denen ein 0 oder "" Standardwert für den linken oder einzigen Operanden sinnvoll ist.
Dies sind: ++ und - (entweder vor oder nach), + =, - =,. =, | =, ^ =, & amp; & amp;;, || =.
Beachten Sie, dass einige von ihnen irrtümlicherweise die Warnung ausgeben, wenn sie in einer gebundenen Variablen verwendet werden: siehe Tests, die in Ссылка .
Wie Brian sagte: Es tut es immer noch, es warnt dich nur. Warnungen informieren Sie über bestimmte Manipulationen mit Effekten, die Sie möglicherweise nicht beabsichtigt haben.
Sie fragen spezifisch nach dem Wert von $histogram{$_}
, fügen 1 hinzu und weisen ihn dann demselben Slot zu. Genauso würde ich nicht erwarten, dass die Autovivifizierung hier funktioniert:
wie hier:
%Vor% Magic funktioniert wahrscheinlich nicht wie Optimierung. Und der optimierende Compiler würde bemerken, dass a = a + 1
dasselbe ist wie a++
, so dass es einen Inkrementoperator in der Assemblersprache geben könnte, könnte er diese optimierte Anweisung verwenden anstatt vorzugeben, dass der erste Wert beibehalten und dann überschrieben werden muss weil es nicht wirklich gebraucht wird.
Die Optimierung ist eine zusätzliche Prüfung und ein zusätzlicher Aufwand, um die Leistung bei jedem Lauf zu verbessern. Aber es gibt keine Garantie in einer dynamischen Sprache, dass Sie keinen Overhead mit der gleichen Rate hinzufügen, wie Sie es sonst versuchen würden, es zu reduzieren.
Tags und Links perl initialization warnings