Что означает предварительное увеличение массива $ #? - PullRequest
5 голосов
/ 02 марта 2009

Я наткнулся на следующую строку кода. У него есть проблемы:

  • предназначен для того же, что и push
  • он должен был использовать толчок
  • трудно читать, понимать
  • С тех пор я изменил его, чтобы использовать push
  • он делает то, что я считал незаконным, но явно не

вот оно:

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

Мой вопрос: что означает предварительное увеличение массива $ #? Я всегда считал массив $ # атрибутом массива и не доступным для записи.

Ответы [ 5 ]

14 голосов
/ 02 марта 2009

perldata говорит:

"Длина массива является скалярным значением. Вы можете найти длину массива @days, оценив $ # days, как в csh. Однако это не длина массива; это индекс индекса последний элемент, который является другим значением, поскольку обычно существует 0-й элемент. Присвоение $ # days фактически изменяет длину массива. Сокращение массива таким образом уничтожает промежуточные значения. Удлинение ранее укороченного массива не восстанавливает значения, которые были в этих элементах. "

Изменение массива $ # полезно в некоторых случаях, но в этом случае явно push лучше.

4 голосов
/ 02 марта 2009

Постинкремент сначала возвращает переменную, а затем увеличивает ее.

Если бы вы использовали постинкремент, вы бы модифицировали последний элемент, так как он возвращался первым, а затем помещали пустой элемент в конец. Во втором цикле вы изменяете это пустое значение и выдвигаете новое пустое значение на потом. Так что это не будет работать как толчок.

Предварительное увеличение будет увеличивать переменную и затем возвращать ее. Таким образом, ваш пример всегда будет записывать новый, последний элемент массива и работать как 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
4 голосов
/ 02 марта 2009

Присвоение значения, превышающего текущую длину массива, $#array расширяет массив.

3 голосов
/ 02 марта 2009

Этот код тоже работает:

$ perl -le 'my @a; $a[@a]="Hello"; $a[@a]=" world!"; print @a'
Hello world!

Массив Perl является динамическим и увеличивается при назначении за пределы.

1 голос
/ 02 марта 2009

Во-первых, это фол.

Тем не менее, я также удивлен, что это работает. Я бы предположил, что ++$#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). Я до сих пор нахожу это уродливым, но, может быть, это только длительное предубеждение "но это число".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...