Можно ли задать несколько переменных одним тернарным оператором? - PullRequest
2 голосов
/ 16 июля 2010

Я искал, можно ли установить несколько переменных одним тернарным оператором.Я немного погуглил, но ничего не придумал.Я начал тестировать несколько идей и нашел что-то близкое - но также получило странное поведение;есть идеи о том, что происходит?И можно ли установить более одной var в одной троичной операции?Если так, есть ли правильный способ сделать это?

$i=9;
($i==9)?($w=3|$r=2):($w=7|$r=1);
echo 'w= '.$w.' r= '.$r;//w= 3 r= 2


$i=9;
($i==9)?($w=4|$r=2):($w=7|$r=1);
echo 'w= '.$w.' r= '.$r;//w= 6 r= 2


$i=9;
($i==9)?($w=3|$r=7):($w=7|$r=1);
echo 'w= '.$w.' r= '.$r;//w= 7 r= 7


$i=444;
($i==9)?($w=4|$r=2):($w=7|$r=1);
echo 'w= '.$w.' r= '.$r;//w= 7 r= 1


$i=444;
($i==9)?($w=4|$r=2):($w=1|$r=1);
echo 'w= '.$w.' r= '.$r;//w= 1 r= 1 

Спасибо ...


Редактировать:

Я провел еще немного испытаний и обнаружил, что это работает правильно:

    ($i==9)?($w=4 AND $r=7):($w=7 AND $r=1);

однако, я не уверен, правильно ли это.И мне любопытно, что происходит в первом примере.

Ответы [ 4 ]

7 голосов
/ 16 июля 2010

Как объяснил Чедвик, использование логических операторов AND или OR не будет работать так, как вы хотите:

$i = 0; $w = 0; $r = 0;
($i==9) ? ($w=4 AND $r=7) : ($w=7 AND $r=1);
echo "w = $w, r = $r\n";
// w = 7, r = 1

$i = 0; $w = 0; $r = 0;
($i==9) ? ($w=0 AND $r=7) : ($w=0 AND $r=1);
echo "w = $w, r = $r\n";
// w = 0, r = 0

Однако, если вы действительно хотите сделать несколько присваиваний одним оператором, вы можете использовать конструкцию list:

$i = 0; $w = 0; $r = 0;
($i==9) ?
    (list($w, $r) = array(4, 7)) :
    (list($w, $r) = array(7, 1));
echo "w = $w, r = $r\n";
// w = 7, r = 1

$i = 0; $w = 0; $r = 0;
($i==9) ?
    (list($w, $r) = array(0, 7)) :
    (list($w, $r) = array(0, 1));
echo "w = $w, r = $r\n";
// w = 0, r = 1
3 голосов
/ 16 июля 2010

Я попытаюсь объяснить, почему ваш текущий код ведет себя так, как он ведет себя. Первое, что нужно знать: | - это побитовый оператор или. Второе, что нужно знать: | имеет более высокий приоритет оператора, чем =, и поэтому выполняется первым.

Итак, давайте посмотрим на первый код: $w=3|$r=2. В соответствии с приоритетом оператора этот код можно записать так: $w=(3|$r=2). Таким образом, $r get установлен правильно и затем выполняется $w=3|2. 3 в двойной системе - 11, а 2 - 10.

  11
| 10
====
  11

Итак, результат верный.

Теперь давайте посмотрим на второй код:

$w=4|$r=2 совпадает с $w=(4|$r=2). $r установлено правильно, затем выполняется $w=4|2. 4 равно 100 в двойной системе, 2 равно 010:

  100
| 010
=====
  110

И 110 в десятичной системе равно 6!

Итак, теперь вы знаете, что получены неправильные значения, теперь давайте найдем решение:

Использование && здесь не рекомендуется, потому что, если первое значение было установлено на 0, второе не будет установлено вообще. Кроме того, он имеет неправильный приоритет оператора: $w=1&&$r=2 совпадает с $w=(1&&$r=2). Так что $w всегда будет присваиваться либо true, либо false.

Одним из возможных решений было бы использование оператора xor. Этот оператор требует выполнения обеих сторон и имеет идеальный приоритет:

$i == 9 ? ($w = 1 xor $r = 2) : ($w = 2 xor $r = 3);

Но, как вы понимаете, это трудно читать, поэтому лучше не используйте его ...

3 голосов
/ 16 июля 2010

Оператор OR сокращает количество вторых назначений, которые вы делаете в выражениях своей троицы.Таким образом, второе присваивание не выполняется, если первое оценивается как ненулевое.

Если вы переключаетесь на AND оценку (или &&), второе присваивание в выражении все еще зависит от первого: если первое значение равно 0 (т. е. ложно), то вторая половина И не оценивается.Это, вероятно, более сложный для отладки, чем первый, поскольку, вероятно, первое значение будет нулевым.Это может никогда не произойти, и это всегда будет работать ... до того дня ...

Тернарный оператор - это просто сокращение для if...else... с одиночными выражениями, а не с множеством операторов.Если вы хотите несколько, независимых назначений, я настоятельно рекомендую придерживаться стандартного if ... else ... Легче читать все вокруг.

0 голосов
/ 16 июля 2010

Вам не хватает символа канала для формирования предложения OR:

($i==9)?($w=3|$r=2):($w=7|$r=1);

Это должно быть:

($i == 9) ? ($w = 3 || $r = 2) : ($w = 7 || $r = 1);

И да, как видно, у вас есть более одноготам используются переменные $w и $r.

...