вторник, 17 июля 2012 г.

Разница между & и &&

Сегодня мы разберемся между особенностями работы операторов & и && в блоках проверки условий.

Пусть у нас есть две функции:
<?php
function f()
{
echo "I am F\n";
return false;
}
function m()
{
echo "I am M\n";
return true;
}
?>
Обратим внимание, функция f возвращает false, а функция m - true. Так и было задумано;)
Теперь исполним в этом же файле следующий код:
<?php
if(f() && m());
?>
Результат будет I am F, то есть, php срабатывает так, что если первая функция возвратила false, то вторая даже не будет исполняться, так как блоку проверки нужно, чтобы обе функции возвратили true, а если одна уже исполнила false - зачем тратить на это время? Аналогично && срабатывает и оператор AND, они есть взаимозаменяемыми.
Теперь сделаем небольшое изменение:
<?php
if(f() & m());
?>
Результат - I am F I am M, то есть, обе функции были исполнены независимо от результата первой! Итак, если первая функция возвратит false и нужно, чтобы вторая при этом не исполнилась - используйте && (он же AND). Но если нужно, чтобы не зависимо от результата исполнилось обе функции, используйте &.
Дальше - больше:
<?php
if(m() || f());
?>
Результат: I am M, так как в результате оптимизации если первое условие возвратило true, следующие условия не будут проверяться.
Чтобы исполнить все функции, вне зависимости от результата первой, делаем так:
<?php
if(m() | f());
?>
В результате получаем I am M I am F, то есть, в этом случае исполняются обе функции.

Я бы назвал это даже больше хаком, чем нормативным использованием кода. Даже если у вас возникнет необходимость в таком поведении кода - обязательно прокомментируйте, зачем это было сделано, это может сбивать с толку или об этом поведении могут не знать другие программисты. При этом будьте внимательны, так как можно попасться на эту особенность самому и длительное время отлавливать баги. Статья даже сделана не для того, чтобы вы сами использовали эти неочевидные поведения кода (ни в коем случае!), а больше для того, чтобы вы знали эту особенность, если увидите чужой код.

1 комментарий:

  1. & и | - побитовые операторы, поэтому сначала вычисляется значение операндов (f() и m()), а потом их сравнение.
    http://php.net/manual/ru/language.operators.bitwise.php

    ОтветитьУдалить