'І' проти '&&' як оператор


298

У мене є кодовий де розробники вирішили використовувати ANDі ORзамість &&і ||.

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

Яку версію ви використовуєте? Чи andчитабельніше, ніж &&? Або різниці немає?


1
Зауважте, що ~це біт-розумний оператор НЕ і не логічний. ;-)
Гумбо

2
Так, я знаю. Шкідливі звички :) . Дещо дивно, що в PHP є "і", "або" і "xor", але немає "не", чи не так?
ц.

1
@ts: правильну відповідь тут є один передбачено Р. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator / ...
Marco DeMaio

4
! є логічним не оператором
Razor Storm

2
@chiliNUT цілком прав. У той час це, мабуть, мало сенс. Схоже, що криється неправильна відповідь була покарана в цей момент :)
doublejosh

Відповіді:


663

Якщо ви користуєтесь 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)

135
+1: це повинно бути чітко і чітко в документації на PHP, або PHP має змінюватися та надавати однакові переваги цим операторам або ВІДМОВИТИ and orраз для всіх. Я бачив занадто багато людей, які думають, що це абсолютно те саме, і відповіді тут - більше відгуків.
Марко Демайо

11
Насправді в інших мовах (наприклад, Perl та Ruby) також є ці варіанти з однаковим відмінністю пріоритету, тому не можна було б відхилятися від цього стандарту (як би це не було дивним для початківців), зробивши пріоритет у PHP. Не кажучи вже про відсталу сумісність тонн програм PHP.
Младен Ябланович

23
Нездатність людей читати документацію на мову не робить неправильні рішення мови. Як зазначає Младен, Perl і Ruby також використовують ці додаткові оператори, і вони мають однакові переваги. Це дозволяє створити такі конструкції, як $foo and bar(), які є хорошими ярликами для операторів if. Якщо несподівана поведінка (від поганої документації чи не читаючи її) була причиною не використовувати щось, ми б взагалі не говорили про використання PHP.
Альтрей

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.


2
Варто зазначити, що "true" не ігнорується, якщо цей вираз є частиною більшого твердження. Розглянемо випадок if ($f = false or true) $f = true;- результатом було б те, $fщо в кінцевому підсумку стає істинним, оскільки вираз оцінюється як істинне загальне.
Кріс Браун

1
ні, ви просто перезаписали змінну пізніше. вираз усе ще оцінюється як хибний, тоді ви перезаписуєте його з істиною в наступному рядку.
r3wt

2
Насправді він мав рацію. По-перше, $fприсвоюється хибне - але умова оцінюється як істинна, тож $fперезаписана Якби умова була оцінена як хибна, $fні в якому разі не було б переписано.
ahouse101

Смішно вважати, що розробники повинні наслідувати власний смак. Забудьте кошмар іншого розробника, який намагається підтримувати той самий код, розробник, який написав сам код, буде робити семантичні помилки в будь-якому коді, написаному тому, що s / він віддав перевагу andнад тим &&, де andпрацює, як очікувалося, лише в деяких ситуаціях і &&працює так, як очікувалося в усіх ситуацій.
ADTC

13

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

if( 
    ((i==0) && (b==2)) 
    || 
    ((c==3) && !(f==5)) 
  )

29
Особисто я думаю, що додавання зайвих дужок в дужках робить його більш заплутаним, ніж просто те, що потрібно. Наприклад, я вважаю, що це набагато простіше читати: якщо (($ i == 0 && $ b == 2) || ($ c == 3 && $ f! = 5))
робі

4
Я думаю, що це найкрасивіший фрагмент коду, який я дивився весь день. Хороша робота.
rm-vanda

Оскільки PHP - це інтерпретована мова, вона працюватиме швидко, якщо ви не використовуєте зайві пробіли чи нові рядки у своєму коді. Якщо ви зробите те ж саме на компільованій мові, то для збирання знадобиться більше часу, але це не вплине на час виконання. Я не маю на увазі, що це зробить один раз, це позначить різницю, але для цілої програми, що використовує php + javascript, написано як приклад ... Час завантаження точно буде більшим. Пояснення: пробіли та нові рядки ігноруються, але щоб їх ігнорувати, їх потрібно перевірити. Це трапляється під час виконання інтерпретованих мов і під час компіляції на компільованих.
JoelBonetR

@JoelBonetR, якщо ви використовуєте php opcache або подібне, ваше занепокоєння щодо часу завантаження не має значення. Я сподіваюся, що без нього ніхто не працює з виробничим php-сайтом ...
PeloNZ

@PeloNZ, щоб ви могли писати брудно, тому що це все одно буде кешовано, і весь проект займе лише секунду більше, щоб завантажити, коли оновити, так? Чистити код - це для вас та ваших товаришів по команді, питання щодо таймінгів було лише моментом, який більшість людей ігнорує або просто не знає.
JoelBonetR

11

Пріоритетність відрізняється між && та ( і & має більшу перевагу ніж та), що викликає плутанину в поєднанні з потрійним оператором. Наприклад,

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

повертає рядок , в той час як

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

поверне буле .


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

2

Дозвольте мені пояснити різницю між "і" - "&&" - "&".

"&&" і "і" - це логічні операції AND, і вони виконують те саме, але пріоритет оператора інший.

Пріоритет (пріоритет) оператора вказує, наскільки "щільно" він пов'язує два вирази разом. Наприклад, у виразі 1 + 5 * 3 відповідь - 16, а не 18, оскільки оператор множення ("*") має вищий пріоритет, ніж оператор додавання ("+").

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


З іншого боку "&" - це побіт І операція . Він використовується для оцінки та маніпулювання певними бітами в цілому значенні.

Приклад, якщо ви зробите (14 і 7), результат буде 6.

7   = 0111
14  = 1110
------------
    = 0110 == 6

1

яку версію ви використовуєте?

Якщо стандарти кодування для певної кодової бази, я пишу код, вказує, який оператор слід використовувати, я обов'язково використовую це. Якщо ні, і код диктує, який слід використовувати (не часто, можна легко обробити), то я буду використовувати це. Інакше, напевно && .

Чи "чи" читабельніше, ніж "&&"?

Це більш читабельним вам . Відповідь " так" і "ні", залежно від багатьох факторів, включаючи код навколо оператора і власне людину, яка його читає!

|| є ~ різниця?

Так. Дивіться логічні оператори для ||та бітових операторів для ~.


0

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

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

true and false || false; // returns true

Отже, використовуючи && та || безпечніше, оскільки вони мають найвищий пріоритет. Що стосується читабельності, я б сказав, що ці оператори є досить універсальними.

ОНОВЛЕННЯ : Щодо коментарів, які говорять про те, що обидві операції повертаються помилково ... ну, насправді код вище нічого не повертає, пробачте за неясність. Для уточнення: поведінка у другому випадку залежить від того, як використовується результат операції. Слідкуйте за тим, як тут грають перевагу операторів:

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

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

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


16
Це неправда, всі вони повертаються помилково.
Jay

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 для детального прикладу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.