'AND' vs '&&' как оператор

298

У меня есть кодовая база, где разработчики решили использовать ANDи ORвместо &&и ||.

Я знаю, что есть различие в приоритетах операторов ( &&идет раньше and), но с данной структурой ( если быть точным, PrestaShop ) это явно не причина.

Какую версию вы используете? Это andболее читабельно, чем &&? Или нет разницы?

ц.
источник
1
Обратите внимание, что ~это побитовый оператор НЕ, а не логический. ;-)
Гамбо
2
Да, я знаю. Плохие привычки :) . Немного странно, что в PHP есть «и», «или» и «xor», но нет «не», не так ли?
ц.
1
@ts: правильный ответ здесь предоставлен R. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator/…
Marco Demaio
4
! логически не оператор
Razor Storm
2
@chiliNUT совершенно верно. В то время это должно было иметь смысл. Похоже, скрывающийся неправильный ответ был наказан в этот момент :)
doublejosh

Ответы:

664

Если вы используете ANDи OR, вы в конечном итоге получите что-то вроде этого:

$this_one = true;
$that = false;

$truthiness = $this_one and $that;

Хотите угадать, что $truthinessравно?

Если вы сказали false... bzzzt, извините, неправильно!

$truthinessвыше имеет значение true. Зачем? =имеет более высокий приоритет, чем and. Добавление скобок для отображения неявного порядка делает это более понятным:

($truthiness = $this_one) and $that

Если вы используете &&вместо andпервого примера кода, он будет работать как положено и будет false.

Как обсуждалось в комментариях ниже, это также работает для получения правильного значения, так как скобки имеют более высокий приоритет, чем =:

$truthiness = ($this_one and $that)
Powerlord
источник
135
+1: это следует сделать громко и ясно в документации PHP, иначе PHP должен измениться и дать одинаковый приоритет этим операторам или DEPRECATE and orраз и навсегда. Я видел слишком много людей, думающих, что они абсолютно одно и то же, и ответы здесь - больше свидетельств.
Марко Демайо
11
На самом деле, другие языки (например, Perl и Ruby) также имеют эти варианты с одинаковым различием приоритетов, поэтому было бы неразумно отступать от этого стандарта (как бы странно это ни было для новичков), делая приоритет в PHP равным. Не говоря уже о обратной совместимости множества PHP-приложений.
Младен Ябланович
23
Неспособность людей читать документацию по языку не делает неправильные решения языка. Как отмечает Младен, Perl и Ruby также используют эти дополнительные операторы с одинаковыми приоритетами. Это позволяет использовать такие конструкции, как $foo and bar(), которые являются хорошими ярлыками для операторов if. Если неожиданное поведение (из-за плохой документации или не чтения) было причиной не использовать то, о чем мы вообще не будем говорить об использовании PHP.
Altreus
2
Я потратил 3 минуты, чтобы найти неправильную строку: $ this = true , :( и как насчет $ правдивости = ($ this и $ that); для меня это выглядит лучше :)
Дмитрий Козьменко
6
Я согласен с Дмитрием - добавление булевой оценки в скобки помогает прояснить смысл кода. Я думаю, что оператор и его функции в том виде, в каком они существуют сейчас, ценны и согласуются с другими языками, программист должен понимать язык.
Jon Z
43

В зависимости от того, как он используется, это может быть необходимо и даже удобно. http://php.net/manual/en/language.operators.logical.php

// "||" has a greater precedence than "or"

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;

Но в большинстве случаев это больше похоже на вкус разработчика, как на каждое вхождение этого, которое я видел в платформе CodeIgniter, как упомянул @Sarfraz.

adamJLev
источник
2
Стоит отметить, что «true» не игнорируется, если это выражение является частью более крупного выражения. Рассмотрим случай if ($f = false or true) $f = true;- в конечном итоге результат $fстанет истинным, поскольку выражение в целом оценивается как истинное.
Крис Браун
1
нет, вы просто переписали переменную позже. выражение по-прежнему оценивается как ложное, затем вы перезаписали его значением true в следующей строке.
r3wt
2
На самом деле он был прав. Сначала $fприсваивается значение false, но условие оценивается как true, а затем $fперезаписывается. Если условие оценивается как ложное, $fоно никогда не будет перезаписано в любом случае.
ahouse101
Смешно предлагать разработчикам следовать своему вкусу. Забудьте кошмар другого разработчика пытается сохранить один и тот же код, разработчик , который написал код сам будет делать смысловые ошибки в любом коде , написанном , потому что он / предпочел andболее &&, где andработает , как ожидается , лишь в некоторых ситуациях и &&работ , как ожидается , во всех ситуации.
ADTC
13

В целях безопасности я всегда заключаю в скобки свои сравнения и выделяю их. Таким образом, мне не нужно полагаться на приоритет оператора:

if( 
    ((i==0) && (b==2)) 
    || 
    ((c==3) && !(f==5)) 
  )
Капитан кенпачи
источник
29
Лично я думаю, что добавление лишних лишних скобок делает чтение более запутанным, чем то, что вам нужно. Например, я думаю, что это намного легче читать: if (($ i == 0 && $ b == 2) || ($ c == 3 && $ f! = 5))
rooby
4
Я думаю, что это самый красивый кусок кода, на который я смотрел весь день. Хорошая работа.
rm-vanda
Поскольку PHP является интерпретируемым языком, он будет работать быстро, если вы не будете использовать ненужные пробелы или новые строки в своем коде. Если вы сделаете то же самое на скомпилированном языке, компиляция займет больше времени, но не повлияет на время выполнения. Я не имею в виду, что если сделать это один раз, это будет означать разницу, но для всего приложения, использующего php + javascript, оба написаны как в примере ... время загрузки наверняка будет больше. Объяснение: Пробелы и новые строки игнорируются, но чтобы их игнорировать, их необходимо проверить. Это происходит во время выполнения на интерпретируемых языках и при компиляции на скомпилированных.
JoelBonetR
@JoelBonetR, если вы используете php opcache или подобное, ваше беспокойство по поводу времени загрузки не имеет значения. Я надеюсь, что никто не запускает производственный php-сайт без него ...
PeloNZ
@PeloNZ, так что вы можете писать грязно, потому что он все равно будет кэширован, и весь проект будет загружаться всего за секунду, когда обновится, а? Чистый код - это для вас и ваших товарищей по команде, забота о времени была лишь точкой, которую большинство людей игнорировали или просто не знали.
JoelBonetR
11

Приоритеты различаются между && и и (&& имеет более высокий приоритет, чем и), что вызывает путаницу в сочетании с троичным оператором. Например,

$predA && $predB ? "foo" : "bar"

вернет строку, тогда как

$predA and $predB ? "foo" : "bar"

вернет логическое значение .

arviman
источник
10

Так как andимеет более низкий приоритет, чем =вы можете использовать его при назначении условий:

if ($var = true && false) // Compare true with false and assign to $var
if ($var = true and false) // Assign true to $var and compare $var to false
Justinas
источник
2

Позвольте мне объяснить разницу между «и» - «&&» - «&».

«&&» и «and» оба являются логическими операциями AND, и они выполняют одно и то же, но приоритет оператора различен.

Приоритет (приоритет) оператора указывает, насколько «тесно» он связывает два выражения вместе. Например, в выражении 1 + 5 * 3 ответом является 16, а не 18, поскольку оператор умножения ("*") имеет более высокий приоритет, чем оператор сложения ("+").

Смешивание их в одну операцию может привести к неожиданным результатам, в некоторых случаях я рекомендую всегда использовать &&, но это ваш выбор.


С другой стороны , «&» является побитовой операцией И . Он используется для оценки и манипулирования конкретными битами в пределах целочисленного значения.

Например, если вы делаете (14 и 7), результат будет 6.

7   = 0111
14  = 1110
------------
    = 0110 == 6
Махмуд Зальт
источник
1

какую версию вы используете?

Если стандарты кодирования для конкретной кодовой базы, для которой я пишу код, определяют, какой оператор следует использовать, я определенно буду это использовать. Если нет, а код диктует, какой должен быть использован (не часто, его легко можно обойти), тогда я воспользуюсь этим. В противном случае, вероятно && .

Является ли 'и' более читабельным, чем '&&'?

Это более читабельно для вас . Ответ - да и нет, в зависимости от многих факторов, включая код оператора и человека, который его читает!

|| есть разница?

Да. Смотрите логические операторы для ||и побитовые операторы для ~.

Salathe
источник
0

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

true && false || false; // returns false

true and false || false; // returns true

Следовательно, используя && и || безопаснее, потому что они имеют высший приоритет. Что касается читабельности, я бы сказал, что эти операторы достаточно универсальны.

ОБНОВЛЕНИЕ : О комментариях, говорящих о том, что обе операции возвращают false ... ну, фактически, приведенный выше код ничего не возвращает, извините за двусмысленность. Для уточнения: поведение во втором случае зависит от того, как используется результат операции. Посмотрите, как приоритет операторов вступает в игру здесь:

var_dump(true and false || false); // bool(false)

$a = true and false || false; var_dump($a); // bool(true)

Причина в том $a === true, что оператор присваивания имеет приоритет над любым логическим оператором, как уже очень хорошо объяснено в других ответах.

nuqqsa
источник
16
Это не правда, они все возвращают ложь.
Джей
0

Вот небольшой контрпример:

$a = true;
$b = true;
$c = $a & $b;
var_dump(true === $c);

вывод:

bool(false)

Я бы сказал, что такого рода опечатка с гораздо большей вероятностью может привести к коварным проблемам (во многом так же, как и к =vs ==) и с гораздо меньшей вероятностью будет замечена, чем adn/ roопечатки, которые будут помечены как синтаксические ошибки. Я также нахожу и / или гораздо легче читать. FWIW, большинство фреймворков PHP, которые выражают предпочтение (большинство не), задают и / или. Я также никогда не сталкивался с реальным, необдуманным случаем, где это имело бы значение.

Синхронная
источник
0

Еще один хороший пример использования ifоператоров без =операций присваивания.

if (true || true && false); // is the same as:
if (true || (true && false)); // TRUE

и

if (true || true AND false); // is the same as:
if ((true || true) && false); // FALSE

потому что ANDимеет более низкий приоритет и, следовательно,|| более высокий приоритет.

Они разные в случаях true, false, falseи true, true, false. См. Https://ideone.com/lsqovs для подробного примера.

кругозор
источник