Почему присвоения в условиях плохой?
Я использую NetBeans для PHP 6.5.
В моем коде я часто использую команду следующего типа:
if (($row = $db->get_row($sql))) {
return $row->folder;
} else {
return FALSE;
}
Netbeans сообщает мне, что я не должен использовать назначения в инструкции IF.
Почему?
Ответы
Ответ 1
Они неплохие, но они могут привести к опасным ошибкам.
В c-подобных языках, где присваивание является выражением (для поддержки, например, a = b = c = 1;), общая ошибка:
if (a = 1) { .. }
Но вы хотели иметь
if (a == 1) { .. }
Некоторые разработчики научились печатать
if (1 == a) { .. }
Чтобы создать ошибку, если один '=' забыли. Но я думаю, что это не улучшает читаемость.
Однако современные компиляторы дают предупреждение, если вы пишете
if (a = 1) { .. }
который я считаю лучшим решением. В этом случае вы должны проверить, действительно ли это было на самом деле.
Ответ 2
Вероятно, это поможет вам избежать страшной опечатки:
if(a = b)
//logic error
Хотя я ожидал бы, что среда достаточно умна, чтобы предупредить вас об этом, а также быть достаточно умным, чтобы условия "о, не волнуйтесь об этом случае".
Ответ 3
Условные часто включают операторы короткого замыкания. Итак, учитывая этот пример:
if ( a=func(x) && b=func(y) )
{
// do this
}
Это может быть не сразу очевидным, но второе присваивание произойдет только в том случае, если первый возвратил >0
, а если func(y)
имел другие побочные эффекты, которые вы ожидали, они тоже не произойдут.
Короче говоря, если вы знаете, что делаете и понимаете побочные эффекты, то в этом нет ничего плохого. Однако вы должны учитывать возможность того, что кто-то еще может поддерживать ваш код, когда вы ушли, и они могут быть не такими опытными, как вы.
Кроме того, будущие сопровождающие могут подумать, что вы планируете следующее:
if ( a==func(x) && b==func(y) ) ...
Если они "исправляют" ваш код, они фактически нарушают его.
Ответ 4
В языках, которые всегда возвращают значение при назначении, это неплохо (я думаю, что это довольно часто встречается в функциональных языках), но (как уже говорили другие, когда я набирал это), его обычно следует избегать, поскольку вы или кто-то другой может ошибаться это для сравнения. Компилятор должен обычно предупреждать об этом, но его можно игнорировать, если вы уверены, что делаете...
Ответ 5
как выглядит код, если вы не присваиваете значение $row в условии цикла
это было бы намного сложнее, я думаю...
хотя не так хорошо читать для некоторых сопровождающих, нет?
хорошо вы можете сделать это, как
$next = mysql_fetch_assoc($result)
do{
...
...
...
$next = mysql_fetch_assoc($result) or break;
}while ($next)
Ответ 6
Я использую их все время, с циклами (не уверен, почему это изменило бы), например:
$counter = 0;
while( $getWhateverDataObj = mysql_fetch_object( $sqlResult )) {
$getWhateverObj->firstName[$counter] = $getWhateverDataObj->firstName;
$getWhateverObj->lastName[$counter] = $getWhateverDataObj->lastName;
$counter++;
}
И он отлично работает.