Операции присваивания

Присваивание переменной какого-либо значения, определенного литералом или выражением, или присваивание одной переменной значения другой переменной является наиболее часто выполняемым действием в программе, написанной на любом языке программирования. В языке Perl присваивание является операцией. Это означает, что при выполнении этой операции происходит не только присваивание значения определенной переменной, но и возвращается некоторое значение. Значение может быть использовано для дальнейших вычислений в сложном выражении, в которое входит сама операция присваивания. В Perl существует одна операция простого присваивания и несколько сложных операций присваивания, заимствованных из языка С.

Операция простого присваивания

Операция простого присваивания (=) является бинарной операцией, правый операнд которой может быть любым правильным выражением, тогда как левый операнд должен определять область памяти, куда операция присваивания помещает вычисленное значение правого операнда. В этом случае говорят, что левый операнд должен быть правильным l-значением. В Perl таковым может быть скалярная переменная, а также массив скаляров, хэш-массив или их элементы. Следующая операция простого присваивания
$a = $b + 3;
вычислит значение правого операнда и присвоит его переменной $a, то есть сохранит в области памяти, выделенной для переменной $a.
Возвращаемым значением операции присваивания в Perl является, в отличие от других языков программирования, в том числе языка С, не присваиваемое значение правого операнда, а ссылка на область памяти, определяемую правильным l-значением левого операнда. В приведенном нами примере — переменной $а. Проще говоря, можно представить себе возвращаемое значение операции простого присваивания как просто переменную, определяемую левым операндом операции присваивания. А коль скоро возвращаемое значение является правильным l-значением, то его снова можно использовать в качестве операнда операции, которой требуется правильное l-значение. Таким образом, в языке Perl следующее выражение
($temp = $а) =~ s/<(.+?)>/<\L$1\U>/g
является синтаксически правильным. Смысл использования подобного выражения в том, что мы применяем результат замены строкового содержимого переменной $а не к ней самой, а к ее копии, сохраненной в переменной $temp.
Синтаксические правила языка Perl позволяют осуществлять присваивание одного и того же значения нескольким переменным в одном выражении:
$var1 = $var2 = $var[0] = 34;
Подобное действие возможно, так как операция простого присваивания обладает свойством сочетаемости справа налево, то есть если в выражении встречается несколько операций присваивания, то они выполняются справа налево. Поэтому в приведенном операторе сначала первому элементу массива скаляров @var будет присвоено значение 34 и возвратится ссылка на область памяти его размещения. В следующей операции присваивания скалярной переменной $var2 будет присвоено значение, содержащееся в первом элементе массива @var1 (оно равно 34), и возвращена ссылка на область памяти расположения переменной $var2. После выполнения последней операции присваивания скалярная переменная $var1 будет иметь такое же значение, что и переменная $var2, и результатом вычисления всего выражения будет ссылка на область памяти, выделенной под переменную $var1, то есть сама переменная $var1.

Операции сложного присваивания

Очень часто при реализации вычислительных алгоритмов приходится использовать значения некоторой переменной и результат присваивать этой же переменной. Например, увеличить на 2 значение переменной $а и результат присвоить этой же переменной $а. Это действие можно реализовать следующей операцией простого присваивания:
$а = $а + 2;
Однако язык Perl предлагает более эффективный способ решения подобных задач, предоставляя в распоряжение программиста бинарную операцию сложного присваивания (+=), которая прибавляет к значению левого операнда, представляющего правильное l-значение, значение правого операнда, и результат присваивает переменной, представленной левым операндом. Таким образом, предыдущий оператор простого присваивания эквивалентен следующему оператору сложного присваивания:
$а += 2; # Результат: $а = $a + 2
Единственное отличие заключается в том, что его реализация эффективнее реализации простого присваивания, так как в составном операторе присваивания переменная $а вычисляется один раз, а в простом ее приходится вычислять дважды. (Под вычислением переменной понимается вычисление адреса представляемой ею области памяти и извлечение значения, хранящегося в этой области памяти.)
Для всех бинарных операций языка Perl существуют соответствующие операции сложного присваивания. Все они, вместе с примерами их использования, собраны в табл. 4.8.
Таблица 4.8. Операции сложного присваивания
Операция Пример Эквивалентная операция простого присваивания
**= $а **= 2; $а = $а ** 2;
+= $а += 2; $а = $а + 2;
-= $а -= 2; $а = $а - 2;
.= $а .= "2"; $а = $а."2";
*= $а *= 2; $а = $а * 2;
/= $а /= 2; $а = $а / 2;
%= $а %= 2; $а = $a % 2;
x= $a x= 2; $а = $а х 2;
&= $а &= $b; $а = $а & $b;
|= $а |= $b; $а = $а | $b;
^= $а ^= $b; $а = $а ^ $b;
<<= $а <<= 2; $а = $а << 2;
>>= $а >>= 2; $а = $а >> 2;
&&= $а &&= $b>0; $a = $a && ($b>0);
||= $а ||= $b == 0; $а = $а || ($b==0);
Возвращаемым значением каждой из операций сложного присваивания, как и в случае простого присваивания, также является ссылка на область памяти, определяемую левым операндом (правильное l-значение). Поэтому эти операции можно использовать в любом операнде других операций присваивания:
$b = 1;
$а = $b += 3; — результат: $а = $b = 4;
$а += $b += 3; - результат = $а=$b+3;
(($а += 2) **= 2) -= 1; - результат $a = ($а + 2) ** 2 - 1
При использовании операции присваивания (простой или сложной) в качестве левого операнда другой операции присваивания обязательно ее заключение в круглые скобки. Иначе может сгенерироваться синтаксическая ошибка или выражение будет интерпретировано не так, как задумывалось. При наличии нескольких операций присваивания в одном выражении без скобок следует помнить, что интерпретатор perl начинает его разбор справа. Например, если последнее выражение из приведенного выше примера записать без скобок: $а += 2 **= 2 -= 1, то при его синтаксическом анализе интерпретатор сначала выделит операцию присваивания 2 -= 1 и тут же сообщит об ошибке, так как ее левый операнд не является правильным l-значением.
ВНИМАНИЕ. Операции сложного присваивания в списковом контексте не используются, поэтому операция @array+=4 приведет к синтаксической ошибке во время компиляции.

Следующая страница Содержание главы


Реклама