Qu'est-ce que cela signifie de pré-incrémenter le tableau $ #?
Question
Je suis tombé sur la ligne de code suivante. Il a des problèmes:
- il est prévu de faire la même chose que push
- il aurait fallu utiliser push
- c'est difficile à lire, à comprendre
- J'ai depuis changé pour utiliser push
- cela fait quelque chose que je pensais être illégal, mais ce n'est clairement pas
la voici:
$array [++$#array] = 'data';
Ma question est la suivante: que signifie pré-incrémenter un tableau $ #? J'ai toujours considéré que $ # array était l'attribut d'un tableau et n'était pas accessible en écriture.
La solution
perldata dit:
"La longueur d'un tableau est une valeur scalaire. Vous pouvez trouver la longueur du tableau @days en évaluant $ # days, comme dans csh. Cependant, ce n'est pas la longueur du tableau; c'est l'indice du dernier élément, qui est une valeur différente puisqu'il y a habituellement un 0ème élément. L'attribution à $ # jours change en réalité la longueur du tableau. Raccourcir un tableau de cette façon détruit les valeurs intermédiaires. L'allongement d'un tableau précédemment raccourci ne récupère pas les valeurs qui se trouvaient dans ces éléments. "
La modification du tableau $ # est utile dans certains cas, mais dans ce cas, il est clair que push vaut mieux.
Autres conseils
Un post-incrément retournera d'abord la variable, puis l'incrémentera.
Si vous utilisiez post-incrémentation, vous modifieriez le dernier élément depuis son premier retour, puis placeriez un élément vide à la fin. Dans la deuxième boucle, vous modifiez cette valeur vide et vous en insérez une nouvelle pour plus tard. Donc, cela ne fonctionnerait pas comme une poussée du tout.
La pré-incrémentation incrémentera la variable puis la renverra. De cette façon, votre exemple sera toujours en train d'écrire sur un dernier et dernier élément du tableau et fonctionnera comme un push. Exemple ci-dessous:
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";
sorties:
pre keys: 3
pre: 2 3
post keys: 3
post: 1 2 3
L'attribution d'une valeur supérieure à la longueur du tableau actuel à $ # array
étend le tableau.
Ce code fonctionne aussi:
$ perl -le 'my @a; $a[@a]="Hello"; $a[@a]=" world!"; print @a'
Hello world!
Le tableau Perl est dynamique et s’agrandit au-delà des limites.
Tout d'abord, c'est injuste.
Cela dit, je suis également surpris que cela fonctionne. J'aurais supposé que ++ $ # array
aurait obtenu le symbole "Ne peut pas modifier constant". erreur que vous obtenez en essayant d'incrémenter un nombre. (Ce n’est pas que j’ai jamais fait cela par hasard, bien sûr.) Mais j’imagine que c’est exactement là où nous nous sommes trompés: $ # array
n’est pas une constante (un nombre); c'est une expression variable. En tant que tel, vous pouvez jouer avec. Considérez ce qui suit:
my @array = qw/1 2 3/;
++$#array;
$array[$#array] = qw/4/;
print "@array\n"
Et même, pour le plus grand plaisir, ceci:
my @array = qw/1 2 3/;
$#array += 5;
foreach my $wtf (@array) {
if (defined $wtf) {
print "$wtf\n";
}
else {
print "undef\n";
}
}
Et oui, le livre de recettes Perl accepte volontiers de manipuler $ # array
pour agrandir ou tronquer des tableaux (Chapitre 4, recette 3). Je le trouve toujours moche, mais peut-être que c'est juste "mais c'est un numéro" préjudice.