В Perl как работает || оператор работает? - PullRequest
6 голосов
/ 19 мая 2011

Так вот

$y = 0 | 2 | 4;  # answer is  6

$x = 0 || 2 || 4;  # answer is 2

Я знаю, почему $y равно 6, потому что он использует оператор OR для каждого числа и 2 | 4 = 6, но для $x ...

Почему это 2?

Ответы [ 4 ]

13 голосов
/ 19 мая 2011

Потому что 2 - это первый не ложный элемент и логическое ИЛИ короткое замыкание. Он оценивает ноль, который является ложным, затем 2, который не является ложным, поэтому он выполняется и возвращает 2. Рассмотрим вывод следующего примера:

$val = 1;
sub a_proc {
    print "a_proc: ", $val++, "\n";
    1;
}
$another_val = &a_proc || &a_proc;

Это выдаст a_proc: 1. Как только a_proc возвращает истинное значение, интерпретатор может прекратить вычисление, поскольку логическое ИЛИ равно true, а любое значение равно true.

8 голосов
/ 19 мая 2011

Это короткое замыкание, сохранение значения логического или.По сути, он оценивает каждую из вещей между || по очереди, пока не найдет ту, которая не является ложной, и в этот момент он возвращает эту единицу и не оценивает никаких последующих операндов.

edit

Есть две важные особенности логических операций Perl

  • они короткое замыкание в том смысле, что они сначала вычисляют левый операнд,и если оно истинно (ложно для &&), НЕ оценивать правильный операнд

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

Обе эти функцииочень важно, и они объединяются, чтобы сделать || особенно полезным в perl - гораздо больше, чем в C / C ++, где он просто закорочен и НЕ сохраняет значения.

5 голосов
/ 19 мая 2011

Хотя операторы выглядят одинаково, их назначение на самом деле другое.

От perldoc perlop :

Binary "||"выполняет операцию логического ИЛИ короткого замыкания.То есть, если левый операнд имеет значение true, правый операнд даже не оценивается.

По сравнению с:

Двоичный "|"возвращает операнды ORed вместе по битам.

Цель || состоит в том, чтобы найти ответ на вопрос "is x || y true или false?", тогда как цель bitwise or- | - это придумать произведение (?) Операндов или что-то вроде «каков результат x | y

Поскольку единственные интересные два результата из || верныили false, утверждение может (и является) замкнутым, вызывая тем самым этот эффект.

В первом утверждении: (0 | 2) = 2, (2 | 4) = 6

Во втором утверждении: (0 || 2) = 2, (2 || ...) = 2

Интересно, что bitwise or устанавливает логические значения внутри двоичного числа.Добавление значения true или false в позиции в двоичном представлении числа.

0000 | 0010 = 0010
0010 | 0100 = 0110
0110 | 0001 = 0111
0111 | 0001 = 0111 # no change

Это очень удобно для хранения нескольких логических значений в одном числе, что можно проверить с помощью & (bitwise AND).

0101 & 0100 = 0100 (true)
0101 & 0010 = 0000 (false)

Существует 10 видов людей: тех, кто понимает двоичные числа, и тех, кто не понимает.

2 голосов
/ 19 мая 2011
EXPR_A || EXPR_B

более или менее эквивалентно

do { my $rv = EXPR_A; if ($rv) { $rv } else { EXPR_B } }

Или по-английски,

  1. Во-первых, он вычисляет EXPR_A в скалярном контексте.
  2. Еслизначение true, это значение возвращается.
  3. Если значение равно false, EXPR_B оценивается и возвращается.

Иногда вы можете увидеть их в цепочке.

EXPR_A || EXPR_B || EXPR_C || EXPR_D

- это просто

( ( EXPR_A || EXPR_B ) || EXPR_C ) || EXPR_D

, поэтому просто примените вышеуказанное рекурсивно.

В результате вы получите результат первого выражения, которое возвращает true, или результат последнего, если ничего неправда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...