Вопрос

Во многих языках назначения являются законными при определенных условиях.Я никогда не понимал причину этого.Зачем вам писать:

if (var1 = var2) {
  ...
}

вместо:

var1 = var2;
if (var1) {
  ...
}
Это было полезно?

Решение

Это более полезно для циклов, чем для операторов if.

while( var = GetNext() )
{
  ...do something with var 
}

Что в противном случае пришлось бы писать

var = GetNext();
while( var )
{
 ...do something
 var = GetNext();
}

Другие советы

Это более полезно, если вы вызываете функцию:

if (n = foo())
{
    /* foo returned a non-zero value, do something with the return value */
} else {
    /* foo returned zero, do something else */
}

Конечно, вы можете просто поставить n = foo();в отдельном операторе then if (n), но я думаю, что приведенное выше — вполне читаемая идиома.

Я считаю, что это наиболее полезно в цепочках действий, которые часто включают обнаружение ошибок и т. д.

if ((rc = first_check(arg1, arg2)) != 0)
{
    report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
    report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
    report error based on new rc
}
else
{
    do what you really wanted to do
}

Альтернатива (без использования присваивания в условии):

rc = first_check(arg1, arg2);
if (rc != 0)
{
    report error based on rc
}
else
{
    rc = second_check(arg2, arg3);
    if (rc != 0)
    {
        report error based on new rc
    }
    else
    {
        rc = third_check(arg3, arg4);
        if (rc != 0)
        {
            report error based on new rc
        }
        else
        {
            do what you really wanted to do
        }
    }
}

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

Проверки ошибок также могут быть «действиями» — first_action(), second_action(), third_action() — конечно, а не просто чеки.То есть можно было бы проверить этапы процесса, которым управляет функция.(Чаще всего в коде, с которым я работаю, функции выполняются по принципу проверки предварительных условий или выделения памяти, необходимой для работы функции, или по аналогичным линиям).

Это может быть полезно, если вы вызываете функцию, которая возвращает либо данные для работы, либо флаг, указывающий на ошибку (или на то, что все готово).

Что-то вроде:

while ((c = getchar()) != EOF) {
    // process the character
}

// end of file reached...

Лично мне эта идиома не очень нравится, но иногда альтернатива оказывается уродливее.

GCC может помочь вам обнаружить (с помощью -Wall), если вы непреднамеренно пытаетесь использовать присваивание в качестве значения истинности, в случае, если он рекомендует вам написать

if ((n = foo())) {
   ...
}

Т.е.используйте дополнительные скобки, чтобы указать, что это действительно то, что вам нужно.

Эта идиома более полезна, когда вы пишете while цикл вместо if заявление.Для if утверждение, вы можете разбить его, как вы описываете.Но без этой конструкции вам придется либо повторяться:

c = getchar();
while (c != EOF) {
    // ...
    c = getchar();
}

или используйте полуторацикловую структуру:

while (true) {
    c = getchar();
    if (c == EOF) break;
    // ...
}

Обычно я предпочитаю форму «полтора петли».

Короткий ответ заключается в том, что Ориентированный на выражение языки программирования позволяют писать более краткий код.Они не заставляют вас отделять команды от запросов.

Например, в PHP это полезно для циклического просмотра результатов базы данных SQL:

while ($row = mysql_fetch_assoc($result)) {
    // Display row
}

Это выглядит намного лучше, чем:

$row = mysql_fetch_assoc($result);
while ($row) {
    // Display row
    $row = mysql_fetch_assoc($result);
}

Другое преимущество возникает при использовании GDB.В следующем коде код ошибки неизвестен, если бы мы выполнили один шаг.

while (checkstatus() != -1) {
    // process
}

Скорее

while (true) {
    int error = checkstatus();
    if (error != -1)
        // process
    else
        //fail
}

Теперь в течение одного шага мы можем узнать, какой был код ошибки возврата из checkstatus().

Причина в следующем:

  1. Улучшение производительности (иногда)

  2. Меньший код (всегда)

Возьмем пример:Существует метод someMethod() и в if условие, в котором вы хотите проверить, является ли возвращаемое значение метода null.Если нет, вы собираетесь использовать возвращаемое значение снова.

If(null != someMethod()){
    String s = someMethod();
    ......
    //Use s
}

Это снизит производительность, поскольку вы вызываете один и тот же метод дважды.Вместо этого используйте:

String s;
If(null != (s = someMethod())) {
    ......
    //Use s
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top