Ich habe gerade mit der Arbeit mit einem neuen Team neuen Ort begonnen. Sie sagten mir, dass wir ref anstelle von Wert in unseren Perl-Modulen zurückgeben. Auch ich sah etwas wie return +{foo=>'bar'}; and return {foo=>'bar'};
Was ist der Unterschied? Und ob Ref oder Wert zurückgeben?Unterschied zwischen der Rückgabe + {} oder {} in Perl von einer Funktion, und Rückgabe ref oder Wert
Antwort
Die +
ist dort völlig nutzlos.
Zuerst einige Hintergrund.
Die Perl-Sprache hat Unklarheiten. Nehmen Sie zum Beispiel
sub f {
{ } # Is this a hash constructor or a block?
}
{ }
ist gültige Syntax für einen Block ("bare-Loop").
{ }
ist gültige Syntax für einen Hash-Konstruktor.
Und beide sind als Aussage erlaubt!
Also muss Perl raten. Perl wird normalerweise richtig geschätzt, aber nicht immer. Sie können es "Hinweise" geben. Unary-+
kann dazu verwendet werden. Unary- +
ist ein vollständig transparenter Operator; es macht gar nichts. Es muss jedoch ein Ausdruck (keine Aussage) folgen. { }
hat nur eine mögliche Bedeutung als Ausdruck.
+{ } # Must be a hash constructor.
In ähnlicher Weise können Sie Perl dazu bringen, den anderen Weg zu erraten.
{; } # Perl looks head, and sees that this must be a block.
Hier ist ein Beispiel, wo Perl falsche Vermutungen:
map { {} } 1..5 # ok. Creates 5 hashes and returns references to them.
map {}, 1..5 # XXX Perl guesses you were using "map BLOCK LIST".
map +{}, 1..5 # ok. Perl parses this as "map EXPR, LIST".
Wie für den Code in der Frage, return
muss durch einen Ausdruck (wenn überhaupt) verfolgt werden, so gibt es nur eine mögliche Interpretation für return { ... };
, so dass die +
dort völlig nutzlos ist.
Die meisten Menschen disambiguieren nur bei Bedarf. Andere könnten +
hinzufügen, wenn es mehrdeutig ist (selbst wenn Perl richtig rät). Aber das ist das erste Mal, dass ich von +
vor jedem Hash-Konstruktor gehört habe.
Sehr schöne Erklärung, die die Mehrdeutigkeit aus der Mehrdeutigkeit entfernt. – stevieb
Beachten Sie, dass seit 'map {}, 1..5;' nur eine gültige Interpretation hat, damit Perl herausfinden kann, was Sie gemeint haben, anstatt zu raten. 1) Das geht davon aus, dass niemand Syntaxfehler macht, und 2) Wenn Sie disambiguieren, disamiguieren Sie nicht nur für Perl, sondern auch für den Leser. Kurz gesagt, es ist am besten, die Bedeutung von Tokens so schnell wie möglich zu kennen. – ikegami
Was ist der Unterschied?
Das sind genau die gleichen, so dass die +
ist fremd. Sie können dies sehen von B::Deparse mit:
$ perl -MO=Deparse -e'sub foo { return { foo => "bar" } }'
sub foo {
return {'foo', 'bar'};
}
-e syntax OK
$ perl -MO=Deparse -e'sub foo { return +{ foo => "bar" } }'
sub foo {
return {'foo', 'bar'};
}
-e syntax OK
In beiden Fällen sind Sie eine Referenz auf einen Hash zurück.
Als Hunter McMillen sagte in einem Kommentar, gibt es einige Fälle, in denen Sie den einstelligen +
Operator verwenden müssen, um Unklarheiten zu lösen.
$ perl -e'@a = map { $_ => "foo" }, 1..3' # { ... } treated as a block
syntax error at -e line 1, near "},"
Execution of -e aborted due to compilation errors.
$ perl -e'@a = map +{ $_ => "foo" }, 1..3' # { ... } treated as a hashref
Und ob zurückzukehren ref oder Wert:
zum Beispiel zwischen einem anonymen Hash und einem Block in einem
map
zu unterscheiden?
Mit „einen Wert zurückgibt:“ Ich nehme an, Ihre Mitarbeiter so etwas wie dies bedeuten:
sub foo {
my %bar = (baz => 'qux');
return %bar; # as opposed to \%bar
}
my %hash = foo();
Subroutinen nur eine Liste der Skalare zurückkehren kann, so ist dies entspricht in etwa
my %hash = ('baz', 'qux');
Wenn %bar
viele Elemente enthält, wird das Kopieren dieser Liste teuer. Daher kann es besser sein, stattdessen eine Referenz zu senden:
sub foo {
my %bar = (baz => 'qux');
return \%bar;
}
my $hashref = foo();
Hinweis: Deparse ist eine gute Referenz, aber es ist nicht endgültig. Wenn Sie einen definitiven Vergleich wünschen, können Sie 'diff -u <(Perl -MO = Concise, -exec, foo -e'sub foo {retour {foo =>" bar "}} '2> & 1) <(perl -MO = Concise, -exec, foo -e'sub foo {return + {foo => "bar"}} '2> & 1) '. – ikegami
- 1. Rückgabe TRUE oder FALSE von einer Funktion
- 2. Unterschied zwischen der Rückgabe eines Elterntyps oder Kindtyps
- 3. Unterschied zwischen der Rückgabe einer const-Referenz und rvalue-Referenz
- 4. Unterschied zwischen Rückgabe und Drucken in Python?
- 5. Mit Funktion zum Einfügen von Datensatz oder Rückgabe ID-Wert
- 6. Rückgabe entweder leer oder numerischer Wert
- 7. Warum gibt es einen Unterschied zwischen dem Wert vor der Rückgabe und dem Wert nach der Rückgabe?
- 8. Was ist der Unterschied zwischen "||" und "oder" in Perl?
- 9. Rückgabe Enum von Funktion C#
- 10. Rückgabe einer abstrakten Klasse von einer Funktion
- 11. Rückgabe große Daten Mitglieder einer Klasse durch Referenz oder Wert
- 12. Unterschied zwischen der Rückgabe von Future.failed (Ausnahme) und dem Auslösen einer Ausnahme
- 13. Rückgabe Wahr oder falsch innerhalb einer Methode
- 14. Rückgabe && Ausdruck von JS-Funktion
- 15. Funktion Service Rückgabe undefined
- 16. Rückgabe nicht in Funktion
- 17. Rückgabe von Daten aus der Datenbank in .net: Rückgabe eines DataTable oder LIst <T>?
- 18. Rückgabe der Unterschied zwischen zwei Listen in Java
- 19. einfache faktorielle Funktion in Perl Fehler: Rückgabe außerhalb einer Subroutine
- 20. Endlose Rückgabe von Wert
- 21. Rückgabe ungültig oder Verweis auf selbst?
- 22. Unterschied zwischen - und - oder 'und' oder "und"
- 23. Keine Rückgabe oder ein Tupel und Auspacken
- 24. Rückgabe config.read() von Funktion
- 25. Rückgabe Ja oder Nein Wert in Feld hat sich geändert
- 26. JavaScript Closure: Rückgabe einer Funktion
- 27. PHP-Rückgabe (Wert); vs Rückgabewert;
- 28. C++ Class Design und Rückgabe von Wert
- 29. Rückgabe oder Übergabe eines Arrays in eine Funktion
- 30. Übernehmen Funktion oder Schleife in R: Nicht numerisch, Rückgabe NA
Es wird gelegentlich verwendet, um zwischen einer HASH-Referenz und einem BLOCK-Ausdruck zu disambiguieren. Sie können mehr darüber unter ['perldoc perlref'] (http://perldoc.perl.org/perlref.html) lesen –
Oh mein Gott. Perl-Standards, geschrieben von Nicht-Perl-Programmierern! Sicherlich müssen Sie nicht 'return \ 1 'schreiben? Aber immer wiederkehrende Hash- oder Array-Referenzen sind ein Rezept für Speicherlecks. – Borodin
"return ref statt value" ... das habe ich gesehen. Das bedeutet normalerweise, dass der Rückgabewert * immer * eine Referenz ist (egal ob Hash, Array usw.), auch wenn er leer ist. Wenn alles in Ordnung ist, erhalten Sie möglicherweise eine aufgefüllte Hash-Referenz, aber bei einem Fehler oder Erfolg, aber nichts erreicht, eine leere ref '{}' (Hash-Ref in diesem Fall). Dann könnte der Aufrufer: 'if (! Exists $ return -> {expected}) {do_something(); ...} ' – stevieb