Что означает предварительное увеличение $#array?
Вопрос
Я встретил следующую строку кода.У него есть проблемы:
- он предназначен для того же, что и push
- следовало бы использовать push
- трудно читать, понять
- С тех пор я изменил его, чтобы использовать push
- он делает то, что я считал незаконным, но это явно не так
вот:
$array [++$#array] = 'data';
Мой вопрос:что означает предварительное увеличение $#array?Я всегда считал $#array атрибутом массива, недоступным для записи.
Решение
перлданные говорит:
«Длина массива является скалярной величиной.Вы можете найти длину массива @days, вычислив $#days , как в csh.Однако это не длина массива;это индекс последнего элемента, который имеет другое значение, поскольку обычно существует 0-й элемент.Присвоение $#days фактически изменяет длину массива.Такое сокращение массива уничтожает промежуточные значения.Удлинение массива, который ранее был сокращен, не восстанавливает значения, которые были в этих элементах».
Изменение $#array полезно в некоторых случаях, но в этом случае явно лучше использовать push.
Другие советы
Постинкремент сначала вернет переменную, а затем увеличит ее.
Если бы вы использовали пост-инкремент, вы бы изменили последний элемент, поскольку он возвращается первым, а затем поместили бы пустой элемент в конец.Во втором цикле вы будете изменять это пустое значение и помещать новое пустое значение на потом.Так что это вообще не будет работать как толчок.
Предварительный приращение увеличит переменную, а затем вернет ее.Таким образом, ваш пример всегда будет записывать новый, последний элемент массива и работать как push.Пример ниже:
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";
выходы:
pre keys: 3
pre: 2 3
post keys: 3
post: 1 2 3
Присвоение значения, большего, чем текущая длина массива, $#array
расширяет массив.
Этот код тоже работает:
$ perl -le 'my @a; $a[@a]="Hello"; $a[@a]=" world!"; print @a'
Hello world!
Массив Perl является динамическим и увеличивается при назначении за пределы.
Прежде всего, это нечестно.
Тем не менее, я также удивлен, что это работает.Я бы догадался, что ++$#array
получил бы ошибку «Невозможно изменить константу», которую вы получаете при попытке увеличить число.(Конечно, не то чтобы я когда-либо случайно это делал.) Но, думаю, именно в этом мы и ошиблись: $#array
не является константой (числом);это переменное выражение.Таким образом, вы можете с этим возиться.Учтите следующее:
my @array = qw/1 2 3/;
++$#array;
$array[$#array] = qw/4/;
print "@array\n"
И даже, для большего удовольствия, вот это:
my @array = qw/1 2 3/;
$#array += 5;
foreach my $wtf (@array) {
if (defined $wtf) {
print "$wtf\n";
}
else {
print "undef\n";
}
}
И да, Поваренная книга Perl рад пообщаться $#array
увеличивать или сокращать массивы (глава 4, рецепт 3).Я до сих пор нахожу это уродливым, но, возможно, это просто устоявшееся предубеждение «но это число».