Perl: ссылка на массив против анонимного массива
это может быть глупый вопрос... Следующий код выводит содержимое @arrayref
и @arraycont
соответственно. Обратите внимание на разницу между ними и способ присвоения им значений. Я знаю, что делает анонимный массив, но может ли кто-нибудь объяснить, почему есть разница?
большое спасибо.
@arrayref = ();
@array = qw(1 2 3 4);
$arrayref[0] = @array;
@array = qw(5 6 7 8);
$arrayref[1] = @array;
print join "t", @{$arrayref[0]}, "n";
print join "t", @{$arrayref[1]}, "n";
@arraycont = ();
@array = qw(1 2 3 4);
$arraycont[0] = [@array];
@array = qw(5 6 7 8);
$arraycont[1] = [@array];
print join "t", @{$arraycont[0]}, "n";
print join "t", @{$arraycont[1]}, "n";
выходы
5 6 7 8
5 6 7 8
1 2 3 4
5 6 7 8
3 ответов
Это создает мелкий копию массива:
$arraycont[0] = [@array];
а это просто создает ссылку на него:
$arrayref[0] = \@array;
так как вы позже измените массив:
@array = qw(5 6 7 8);
arrayref
все еще указывает на то же расположение массива в памяти, и поэтому при разыменовании в операторах печати он печатает текущие значения массива 5 6 7 8
.
в первом блоке хранится адрес @ array. Ссылки вроде 'live streaming', вы получаете текущее состояние. Поэтому, если вы создадите ссылку на @ array, как \@array, когда вы де-ссылки вы всегда будете получать то, что @ array точки в момент отсчета. Когда вы де-см. @ array было (5 6 7 8)
когда вы [@array] его как запись в прямом эфире на диске. Поэтому, когда вы (re)воспроизводите записанный контент, вы получаете то, что было
транслировалось во время записи. Поэтому, когда вы ссылаетесь $arraycont[0] вы получаете @ array был в момент копирования, то есть
(1 2 3 4)
вы сделали сохраненные ссылки на один массив в обоих $arrayref[0]
и $arrayref[1]
. Вы
должны были использовать разные массивы.
my @refs;
my @array1 = qw(1 2 3 4);
push @refs, \@array1;
my @array2 = qw(5 6 7 8);
push @refs, \@array2;
на практике my
выполняется в каждом проходе цикла, создавая каждый раз новый массив.
my @refs;
while ( my @row = get() ) {
push @refs, \@row;
}
в редких случаях, когда вам нужно клонировать массив, вы можете использовать:
use Storable qw( dclone );
push @refs, [ @row ]; # Shallow clone
push @refs, dclone(\@row); # Deep clone