Шаг 78.
Операции присваивания

    На этом шаге мы рассмотрим различные операцтт присваивания.

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

    Операция присваивания = является бинарной операцией, правый операнд которой может быть любым правильным выражением, тогда как левый операнд должен определять область памяти, куда операция присваивания помещает вычисленное значение правого операнда. В этом случае и говорят, что левый операнд должен быть правильным lvalue (от английского left value - левое значение). А что мы можем использовать в программе для обозначения области памяти? Правильно, переменные. Следовательно, в качестве левого операнда операции присваивания можно использовать переменную любого типа или элемент любого массива. (В языке Perl существуют и другие объекты, которые можно использовать в качестве левого операнда операции присваивания.) Следующая операция простого присваивания

    $а = $b + 3;
вычислит значение правого операнда и присвоит его переменной , т.е. сохранит в области памяти, выделенной для переменной . Возвращаемым значением этой операции будет адрес области памяти переменной (правильное lvalue), или говоря проще, имя скалярной переменной , которое снова можно использовать в качестве левого операнда операции присваивания. Таким образом, в языке Perl следующая операция присваивания
    ($а = $b) = 3;
является синтаксически правильной и в результате ее вычисления переменной будет присвоено значение 3, так результатом вычисления операции присваивания $а = $b будет присвоение переменной значения переменной $b, а возвращаемым значением можно считать переменную , которой в следующей операции присваивается значение 3. Читатель спросит: "А зачем городить такие сложности, если тот же самый результат можно получить простой операцией присваивания $а = 3?". Действительно, замечание справедливое. Но на этом примере мы показали, как можно использовать операцию присваивания в качестве правильного lvalue. Более интересные примеры мы покажем, когда определим составные операции присваивания, заимствованные из языка С.

    Синтаксические правила языка Perl позволяют осуществлять присваивание одного и того же значения нескольким переменным в одном выражении:

    $var1 = $var2 = $var1[0] = 34;

    Очень часто при реализации вычислительных алгоритмов приходится осуществлять разнообразные вычисления с использованием значения некоторой переменной и результат присваивать этой же переменной. Например, увеличить на 3 значение переменной и результат присвоить этой же переменной . Это действие можно реализовать следующей операцией присваивания:

    $а = $а + 3;

    Однако, язык Perl предлагает более эффективный способ решения подобных проблем, предоставляя в распоряжение программиста бинарную операцию составного присваивания +=, которая прибавляет к значению левого операнда, представляющего правильное lvalue, значение правого операнда и результат присваивает переменной, представленной левым операндом. Таким образом, оператор составного присваивания

    $а += 3; # Результат: $а = $а+3
эквивалентен предыдущему оператору простого присваивания. Единственное отличие заключается в том, что его реализация эффективнее реализации простого присваивания, так как в составном операторе присваивания переменная вычисляется один раз, тогда как в простом ее приходится вычислять дважды. (Под вычислением переменной понимается вычисление адреса представляемой ею области памяти и извлечение значения, хранящегося в этой области памяти.)

    Для всех бинарных операций языка Perl существуют соответствующие составные операции присваивания. Все они, вместе с примерами их использования, собраны в таблице 1.

Таблица 1. Составные операции присваивания
Операция Пример Эквивалент с операцией простого присваивания
**= $а **= 3; $а = $а ** 3;
+= $а += 3; $а = $а + 3;
-= $а -= 3; $а = $а - 3;
.= $а .= "а"; $а = $а . "а ";
*= $а *= 3; $а = $а * 3;
/= $а /= 3; $а = $а / 3;
%= $а %= 3; $а = $а % 3;
x= $а x= 3; $а = $а x 3;
&= $а &= $b; $а = $а & $b;
|= $а |= 3; $а = $а | 3;
^= $а ^= 3; $а = $а ^ 3;
<<= $а <<= 3; $а = $а << 3;
>>= $а >>= 3; $а = $а >> 3;
&&= $а &&= $b > 1; $а = $а && $b > 1;
||= $а ||= $b == 0; $а = $а || $b ==0;

    Возвращаемым значением каждой из составных операций присваивания, как и в случае простого присваивания, является переменная левого операнда (правильное lvalue), поэтому их можно использовать в любом операнде других операций присваивания:

  $b = 1;
  $а = ($b += 3);           # Результат: $а = $b = 4
  $а += ($b += 3);          # Результат: $а = $а+$b+3
  ( ($а += 2) **= 2)  -= 1; # Результат: $а = ($а+2)**2-1


    Замечание. При использовании операции присваивания (простой или составной) в качестве левого операнда другой операции присваивания обязательно ее заключение в круглые скобки. Иначе может сгенерироваться синтаксическая ошибка, или выражение будет интерпретировано не так, как задумывалось. При наличии нескольких операций присваивания в одном выражении без скобок интерпретатор Perl начинает его разбор справа. Например, если последнее выражение приведенного выше примера записать без скобок
  $а += 2 **= 2 -= 1;
то при его синтаксическом анализе интерпретатор сначала выделит операцию присваивания
  2 -= 1;
и сообщит об ошибке, так как ее синтаксис ошибочен (левый операнд не является переменной или элементом массива).

    На следующем шаге мы рассмотрим операции связывания.




Предыдущий шаг Содержание Следующий шаг