Nehmen wir an, das mehrdimensionale Array ist wie folgt:

$myarray = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]];

Der Versuch, auf drei Arten darauf zuzugreifen,

print $myarray->[1][1] #prints 5
print $myarray->[1]->[1] #also prints 5
print $myarray[1][1] #prints nothing

Ich kann den Unterschied zwischen der ersten und der zweiten Art des Zugriffs nicht erkennen. Insbesondere ist der zweite expliziter, aber der erste funktioniert immer noch. Das zwingt mich zu der Annahme, dass die dritte bessere Arbeit auch funktioniert (was ich nicht weiß, weil myarray tatsächlich eine Referenz und kein Array ist).

2
Apvast 18 Jän. 2019 im 19:18

3 Antworten

Beste Antwort

Drei Punkte

  1. $ myarray enthält eine Array-Referenz, kein Array.
  2. $ mayarray und @myarray sind verschiedene Variablen
  3. Perl macht nicht wirklich mehrdimensionale Arrays

Alle Referenzen werden in Skalaren gespeichert, daher werden alle Referenzen in Variablen gespeichert, die mit $ beginnen.

Das [ ... ] erstellt eine anonyme Array-Referenz, sodass [ [1, 2, 3], [4, 5, 6], [7, 8, 9]] eine anonyme Array-Referenz mit 3 anonymen Array-Referenzen mit jeweils 3 Skalaren erstellt.

Dies bedeutet, dass die Zuweisung zu $ myarray den äußeren anonymen Array-Verweis darauf zuweist.

Damit zwei auf das zugreifen können, worauf eine Referenz zwei zeigt, müssen Sie sie dereferenzieren. Sie können dies tun, indem Sie das Symbol für den Typ, auf den die Referenz zeigt, wie @$myarray vor die Referenz setzen. $$myarray[0] ist also das erste Element des anonymen Arrays in der Referenz $myarray, oder Sie können die indirekte Syntax $myarray->[0] verwenden.

In Ihrem Beispiel enthält $myarray->[0] die Array-Referenz [1,2,3]. Dies kann also auf die gleiche Weise referenziert werden, indem $myarray->[0]->[0] angegeben wird. Dies sagt Dereferenzierung $myarray und gibt mir das erste Element, nämlich eine Array-Referenz, dann dereferenziere das und gib mir das erste Element davon.

Dies gibt Ihr zweites Beispiel.

Mit Perl können Sie die -> zwischen ] und [ sowie } und { für anonyme Hashes als syntaktischen Zucker ablegen. Dies ergibt $myarray->[0][0], das Ihr erstes Beispiel ist.

Ihr drittes Beispiel sucht nach dem ersten Element von @myarray, das eine andere Variable als $myarray ist. Wenn Sie use strict an die Spitze Ihres Skripts gesetzt hätten, hätte Perl diesen Fehler für Sie abgefangen.

Es ist eine gute Idee zu setzen

use strict;
use warnings;

Als die ersten beiden Zeilen eines Perl-Skripts oder -Moduls werden sie eine Vielzahl von fehlerhaften und möglicherweise schwerwiegenden Fehlern in Ihrem Programm einfangen. Wenn Sie ein Programm debuggen, erhalten Sie durch Hinzufügen von use diagnostics unter use strict ausführlichere Meldungen.

3
JGNI 22 Jän. 2019 im 08:48

Das erste und zweite Beispiel sind funktional äquivalent. Einer ist nur syntaktischer Zucker für den anderen.

Der dritte ist semantisch anders. Während es akzeptabel ist, -> -Operatoren zwischen Indizes wegzulassen, ist es nicht akzeptabel, dies zwischen Bezeichnern oder Unterprogrammaufrufen und Indizes zu tun, wenn die Variable (oder Unterroutine) eine Referenz enthält (oder zurückgibt), da Perl diese als behandelt Nichtreferenzen in diesem Fall.

Es gibt keine Situation, in der $array->[1][2] etwas anderes als $array->[1]->[2] bedeuten könnte. Wenn es jedoch zulässig wäre, den Pfeil zwischen dem Bezeichner und dem ersten Index wegzulassen, wäre es nicht eindeutig, ob die Struktur indiziert wird sah aus wie [1,...] oder (1,...), die verschiedene Dinge sind.

4
DavidO 18 Jän. 2019 im 16:36

$myarray->[1] bedeutet "Index 1 in einem Array anhand der in $myarray gespeicherten Array-Referenz nachschlagen".

$myarray[1] bedeutet "Index 1 im Array @myarray nachschlagen".

Die beiden Variablen $myarray und @myarray haben überhaupt keine Verbindung.

2
Dave Cross 18 Jän. 2019 im 17:10