Создание массивов ссылок на скаляры
Проблема
Требуется создать массив ссылок на скаляры. Такая задача часто возникает при передаче
функциям переменных по ссылке, чтобы функция могла изменить их значения.
Решение
Чтобы создать массив, либо снабдите префиксом \ каждый скаляр в списке:
@array_of_scalar_refs = ( \$а, \$b );
либо просто поставьте \ перед всем списком, используя свойство дистрибутивности оператора \:
@array_of_scalar_refs = \( $а, $b );
Чтобы получить или задать значение элемента списка, воспользуйтесь конструкцией ${...}:
${ $array_of_scalar_refs[1] } = 12; # $b = 12
Комментарий
В следующих примерах предполагается, что @аrrау — простой массив, содержащий ссылки
на скаляры (не путайте массив ссылок со ссылкой на массив). При косвенных обращениях к
данным необходимы фигурные скобки.
($а, $b, $c, $d) = (1..4); # Инициализировать
@array = (\$a, \$b, \$c, \$d); # Ссылки на все скаляры
@array = \( $а, $b, $c, $d); # To же самое!
${ $array[2] } += 9; # $с = 12
${ $array[ $#array ] } *= 5; # $d = 20
${ $array[-1] } *= 5; # То же; $d = 100
$tmp = $array[-1]; # Использование временной переменной
$$tmp *= 5; # $d = 500
Две формы присваивания @array эквивалентны — оператор \ обладает свойством дистрибутивности.
Следовательно, \ перед списком (но не массивом!) эквивалентно применению \ к каждому элементу
списка. Следующий фрагмент изменяет значения переменных, ссылки на которые хранятся в массиве.
А вот как работать с массивом без явного индексирования.
use Math::Trig qw(pi); # Загрузить константу pi
foreach $sref (@array) { # Подготовиться к изменению $a,$b,$c,$d
($$sref **= 3) *= (4/3 * pi); # Заменить объемом сферы
}
В этом фрагменте используется формула вычисления объема сферы:
V = 4/3*pi*p3.
Переменная цикла $sref перебирает все ссылки @array, а в $$sref заносятся сами числа,
то есть исходные переменные $а, $b, $с и $d. Изменение $$sref в цикле приводит к изменению
этих переменных. Сначала мы возводим $$sref в куб, а затем умножаем полученный результат на 4/З*pi.
При этом используется то обстоятельство, что присваивание в Perl возвращает левостороннее выражение.
Это позволяет сцеплять операторы присваивания, как это делается с операторами **= и *=.
Вообще говоря, анонимные скаляры обычно бесполезны — ведь скалярная величина занимает
столько же места, что и ссылка на нее. По этой причине не предусмотрены и специальные конструкции
для их создания. Скалярные ссылки существуют только для поддержки синонимов, которые могут быть
реализованы и другими способами.
См. также
Proverte kod v komentariyah gde pro list tam oshibki detskie
Оставить комментарий:
|
|