Ссылки на массивы
Проблема
Требуется работать с массивом через ссылку.
Решение
Ссылка на массив создается следующим образом:
$aref = \@array;
$anon_array = [1, 3, 5, 7, 9];
$anon_copy = [ @array ];
@$implicit_creation = (2, 4, 6, 8, 10);
Чтобы разыменовать ссылку на массив, поставьте перед ней символ @:
push(@$anon_array, 11);
Или воспользуйтесь стрелкой с указанием индекса конкретного элемента в квадратных скобках:
$two = $implicit_creation->[0];
Для получения индекса последнего элемента массива по ссылке или определения количества
элементов в массиве применяется следующая запись:
$last_idx = $#$aref;
$num_items = @$aref;
Дополнительные фигурные скобки повышают надежность и форсируют нужный контекст:
$last_idx = $#{ $aref };
$num_items = scalar @{ $aref };
Комментарий
Рассмотрим примеры использования ссылок на массивы:
# Проверить, содержит ли $someref ссылку на массив
if (ref($someref) ne 'ARRAY') {
die "Expected an array reference, not $someref\n";
}
print "@{$array_ref}\n"; # Вывести исходные данные
@order = sort @{ $array_ref }; # Отсортировать их
push @{ $array_ref }, $item; # Добавить в массив новый элемент
Если вы не можете выбрать между использованием ссылки на именованный массив и созданием
нового массива, существует простое правило, которое в большинстве случаев оказывается верным.
Получение ссылки на существующий массив используется либо для возврата ссылки за пределы области
действия, либо при передаче массива функции по ссылке. Практически во всех остальных случаях
используется [@аrrау], что приводит к созданию ссылки на новый массив с копиями старых значений.
Автоматический подсчет ссылок в сочетании с оператором \ обладает большими возможностями:
sub array_ref {
my @array;
return \@array;
}
$aref1 = array_ref();
$aref2 = array_ref();
При каждом вызове array_ref функция выделяет для @array новый блок памяти. Если бы мы не
вернули ссылку на @аrrау, то занимаемая массивом память была бы возвращена при выходе из блока,
то есть при завершении подпрограммы. Однако ссылка на @аrrау продолжает существовать, поэтому
Perl не освобождает память, и мы получаем ссылку на блок памяти, недоступный через таблицу
символов. Такие блоки памяти называются анонимными, поскольку с ними не связано никакое имя.
К определенному элементу массива, на который указывает ссылка $aref, можно обратиться в
форме $$aref [4], но $aref->[4] делает то же самое и обладает большей наглядностью.
print $array_ref->[$N]; # Обращение к N-му элементу (лучший вариант)
print $$array_ref[$N]; # To же, но менее наглядно
print ${$array_ref}[$N]; # То же, но непонятно и уродливо
Имея ссылку на массив, можно получить срез субъектного массива:
@$pie[3..5]; # Срез массива, но читается плохо
@{$pie}[3..5]; # Срез массива, читается лучше (?)
Срезы массивов, даже при обращении через ссылки, допускают присваивание. В следующей
строке сначала происходит разыменование массива, после чего элементам среза присваиваются значения:
@{$pie}[3..5] = ("blackberry", "blueberry", "pumpkin");
Срез массива полностью идентичен списку отдельных элементов. Поскольку ссылку на
список получить нельзя, вам не удастся получить ссылку на срез массива:
$sliceref = \@{$pie}[3..5]; # НЕВЕРНО!
Для перебора в массиве применяется цикл fоreach или for:
foreach $item ( @{$array_ref} ) {
# Данные в $item
}
for ($idx = 0; $idx <= $#{ $array_ref }; $idx++) {
# Данные в $array_ref->[$idx]
}
См. также
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|