Frage Übergeben von Arrays an Funktionen in Perl


Ich denke, ich habe einige Aspekte des Arguments missverstanden, die an Funktionen in Perl übergeben werden. Was ist der Unterschied zwischen func(\@array) und func(@array)?

AFAIK, in beiden Funktionen werden Argumente durch Verweis übergeben und in beiden Funktionen können wir die Elemente ändern @array im Hauptprogramm. Was ist der Unterschied? Wann sollten wir welche verwenden?

@array = (1,2,3);
func(@array);
func(\@array);

sub func {
    ...
}

Wie ahmt ich auch den Wert "pass-by-value" in Perl nach? Benutzt @_ der einzige Weg?


14
2017-08-30 01:14


Ursprung


Antworten:


AFAIK, in beiden Funktionen werden Argumente als Referenz übergeben und in beiden Funktionen können wir die Elemente von @array im Hauptprogramm ändern.

"Ändere die Elemente von", ja. Jedoch in der func(@array) In diesem Fall hat das Sub-Objekt keine Möglichkeit, andere Änderungen am Array vorzunehmen (es zu kürzen, zu schieben, zu poppen, zu schneiden, einen Verweis auf etwas anderes zu übergeben, es sogar zu deaktivieren).

Ich würde vermeiden, den Begriff "durch Verweis" zu verwenden, da der Mechanismus völlig anders ist als die Referenzen von Perl. Es ist weniger überlastet :) zu sagen, dass in der Sub, @_Die Elemente beginnen mit Aliasing zu den Elementen, die an das Sub-Element übergeben werden.


12
2017-08-30 02:36



Es ist unmöglich, Arrays an Subs zu übergeben. Subs nehmen eine Liste von Skalaren für Argumente. (Und das ist das einzige, was sie auch zurückgeben können.)

Sie können einen Verweis auf ein Array übergeben:

func(\@array)

Sie können die Elemente eines Arrays übergeben:

func(@array)

Wann sollten wir welche verwenden?

Wenn Sie mehr als nur die Elemente des Arrays übergeben möchten (z. B. pass $x, $y und @a), kann es schwierig werden, wenn Sie eine Referenz übergeben.

Wenn Sie Listen bearbeiten werden (z. sum mysub grep { ... } ...), möchten Sie vielleicht keine Referenz weitergeben.

Wenn Sie das Array ändern möchten (statt nur die vorhandenen Elemente des Arrays zu ändern), müssen Sie eine Referenz übergeben.

Es kann effizienter sein, einen Verweis für lange Arrays zu übergeben, da das Erstellen und Platzieren eines Verweises auf dem Stapel schneller ist als das Erstellen eines Alias ​​für jedes Element eines großen Arrays. Dies wird jedoch selten ein Problem sein.

Es wird normalerweise von einem der ersten zwei der oben genannten entschieden. Darüber hinaus ist es meist eine Frage der persönlichen Präferenz.


Wie ahmt ich auch den Wert "pass-by-value" in Perl nach?
sub foo {
   my ($x) = @_;   # Changing $x doesn't change the argument.
   ...
}

sub foo {
   my @a = @_;   # Changing @a or its contents
   ...           #    doesn't change the arguments.
}

19
2017-08-30 02:14



func(\@array) übergibt eine Referenz. func(@array) übergibt eine Liste (der Elemente in @array). Wie Keith sagte, werden diese Elemente als Referenz übergeben. Sie können jedoch eine Kopie innerhalb des Subs erstellen, um den Wert zu übergeben.

Was du willst, ist folgendes:

sub func {
    my @array = @_;
}

Dies wird eine Kopie der Argumente von übergeben func zu @arrayDies ist eine lokale Variable im Rahmen des Unterprogramms.

Dokumentation Hier


4
2017-08-30 01:17