Почему назначение ссылки на список переменной массива в Perl работает? - PullRequest
2 голосов
/ 09 июля 2020

У меня есть следующие три назначения, из которых второе выглядит нестандартно:

my $realRef = [1, 2, 3];
my @nonRef  = [4, 5, 6];
my $nonRef  = [7, 8, 9];

Второе действительно должно быть следующим:

my @nonRef  = (4, 5, 6);

При печати , все три переменные содержат ссылки на массивы, и особенно переменные с одинаковыми именами, отличающиеся только @ и $, не используют одни и те же данные и не перезаписывают друг друга.

Ref: ARRAY(0x1fd6a8); $VAR1 = [
          1,
          2,
          3
        ];
Ref: ARRAY(0x6445d8); $VAR1 = [
          4,
          5,
          6
        ];
Ref: ARRAY(0x644740); $VAR1 = [
          7,
          8,
          9
        ];

Почему @nonRef содержит ссылка на массив вообще? Это хранится в $nonRef записи таблицы символов для nonRef или что-то в этом роде? И почему значения @nonRef и $nonRef не перекрываются? Разве оба не ссылаются на одну и ту же запись в таблице символов только с разными слотами, ARRAY против SCALAR? Поскольку обе ссылки на хранилище в конце концов, я ожидал, что будет использоваться одна и та же запись таблицы символов со слотом SCALAR.

Спасибо!

Ответы [ 2 ]

5 голосов
/ 09 июля 2020

Второй такой же, как my @nonRef = ([4, 5, 6]), то есть вы просто помещаете ссылку на массив в $nonRef[0].

2 голосов
/ 09 июля 2020

Вы создаете одноэлементный массив, состоящий из ссылки на массив.

Сколько скаляров вы назначаете массиву, это количество элементов в массиве.

my @a = 4;
# my @a;
# $a[0] = 4;

my @a = 4..6;
# my @a;
# $a[0] = 4;
# $a[1] = 5;
# $a[2] = 6;

[4, 5, 6] создает один скаляр (ссылку на массив), поэтому my @nonRef = [4, 5, 6]; создает массив который содержит одно значение (ссылку).

my @nonRef = [4, 5, 6];
# my @nonRef;
# $nonRef[0] = [4, 5, 6];

Обратите внимание на полное отсутствие скобок в приведенных выше примерах. Родители не создают никаких значений / переменных, как это делают [] и {}. Они просто отменяют приоритет, как в математике. Они ни в коем случае не нужны в правой части присваивания массиву. Единственная причина, по которой мы обычно видим их в правой части назначений, заключается в том, что

my @a = 4, 5, 6;

эквивалентно

( my @a = 4 ), 5, 6;   # Only assigns 4 to the array.

Для субмарины без прототипов

f(@a)

совпадает с

f($a[0], $a[1], ...)

Итак, когда вы сделали

print(Dumper(@nonRef));

, это как если бы вы сделали

print(Dumper($nonRef[0]));

Я предпочитаю использовать

print(Dumper(\@nonRef));
...