5 Stimmen

Was bedeutet es, $#array vorab zu erhöhen?

Ich bin auf die folgende Codezeile gestoßen. Es hat Probleme:

  • Es soll dasselbe wie push machen
  • Es hätte push verwenden sollen
  • Es ist schwer zu lesen, zu verstehen
  • Ich habe es seitdem geändert, um push zu verwenden
  • Es tut etwas, von dem ich dachte, dass es illegal ist, aber offensichtlich nicht

Hier ist es:

$array [++$#array] = 'Daten';

Meine Frage ist: Was bedeutet es, $#array vorzuinkrementieren? Ich habe immer $#array als ein Attribut eines Arrays betrachtet und nicht beschreibbar.

14voto

ysth Punkte 91645

perldata sagt:

"Die Länge eines Arrays ist ein skalaren Wert. Sie können die Länge des Arrays @days ermitteln, indem Sie $#days auswerten, wie in csh. Das ist jedoch nicht die Länge des Arrays; es ist der Index des letzten Elements, was ein anderer Wert ist, da normalerweise ein 0-tes Element vorhanden ist. Das Zuweisen zu $#days ändert tatsächlich die Länge des Arrays. Das Verkürzen eines Arrays auf diese Weise zerstört eingreifende Werte. Eine Verlängerung eines zuvor verkürzten Arrays stellt nicht die Werte wieder her, die in diesen Elementen enthalten waren."

Die Modifizierung von $#array ist in einigen Fällen nützlich, aber in diesem Fall ist eindeutig push besser.

4voto

Manu Punkte 28059

Weist man $#array einen Wert zu, der größer ist als die aktuelle Array-Länge, so wird das Array erweitert.

4voto

mleykamp Punkte 1326

Ein Post-Increment gibt zuerst die Variable zurück und inkrementiert sie dann.

Wenn Sie das Post-Increment verwendet hätten, würden Sie das letzte Element ändern, da es zuerst zurückgegeben wird, und dann ein leeres Element am Ende hinzufügen. In der zweiten Schleife würden Sie diesen leeren Wert ändern und später ein neues leeres Element hinzufügen. Daher funktioniert es überhaupt nicht wie ein push.

Das Pre-Increment wird die Variable inkrementieren und sie dann zurückgeben. Auf diese Weise wird Ihr Beispiel immer in ein neues, letztes Element des Arrays schreiben und wie ein push funktionieren. Beispiel unten:

my (@pre, @post);

$pre[$#pre++] = '1';
$pre[$#pre++] = '2';
$pre[$#pre++] = '3';

$post[++$#post] = '1';
$post[++$#post] = '2';
$post[++$#post] = '3';

print "pre keys: ".@pre."\n";
print "pre: @pre\n";
print "post keys: ".@post."\n";
print "post: @post\n";

Ausgabe:

pre keys: 3
pre: 2 3
post keys: 3
post: 1 2 3

3voto

Dieser Code funktioniert auch:

$ perl -le 'my @a; $a[@a]="Hallo"; $a[@a]="Welt!"; print @a'
Hallo Welt!

Perl-Array ist dynamisch und wächst, wenn es über die Grenzen hinaus zugewiesen wird.

1voto

Telemachus Punkte 18969

Zunächst einmal ist das unfair.

Trotzdem bin ich auch überrascht, dass es funktioniert. Ich hätte vermutet, dass ++$#array den Fehler "Kann die Konstante nicht ändern" erhalten hätte, den man erhält, wenn man versucht, eine Zahl zu erhöhen. (Das passiert mir natürlich nicht versehentlich.) Aber anscheinend haben wir uns genau in diesem Punkt geirrt: $#array ist keine Konstante (eine Zahl); es ist ein Variablenausdruck. Als solches kannst du damit spielen. Betrachten wir das folgende Beispiel:

my @array = qw/1 2 3/;

++$#array;
$array[$#array] = qw/4/;

print "@array\n"

Sogar für extra Spaß, dies hier:

my @array = qw/1 2 3/;

$#array += 5;

foreach my $wtf (@array) {
  if (defined $wtf) {
    print "$wtf\n";
  }
  else {
    print "undef\n";
  }
}

Und ja, das Perl Cookbook ist glücklich darüber, mit $#array zu spielen, um Arrays zu erweitern oder zu kürzen (Kapitel 4, Rezept 3). Ich finde das immer noch hässlich, aber vielleicht ist es nur ein hartnäckiges Vorurteil "aber es ist eine Zahl".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X