Подтвердить что ты не робот

Почему "еще" редко используется после "если х затем вернуться"?

Этот метод:

boolean containsSmiley(String s) {
    if (s == null) {
        return false;
    }
    else {
        return s.contains(":)");
    }
}

можно равнозначно записать:

boolean containsSmiley(String s) {
    if (s == null) {
        return false;
    }

    return s.contains(":)");
}

По моему опыту, вторая форма рассматривается чаще, особенно в более сложных методах (там, где может быть несколько таких точек выхода), и то же самое верно для "броска", а также "возврата". Тем не менее первая форма, возможно, делает условную структуру кода более явной. Есть ли какие-то причины предпочесть друг другу?

(Связано: Если функция имеет только один оператор return?)

4b9b3361

Ответ 1

По моему опыту, это зависит от кода. Если я "защищу" от чего-то, я сделаю:

if (inputVar.isBad()) {
    return;
}

doThings();

Ясно. Если это утверждение ложно, я не хочу, чтобы функция продолжалась.

С другой стороны, есть несколько функций с несколькими опциями, и в этом случае я бы написал это следующим образом:

if (inputVar == thingOne) {
    doFirstThing();
} else if (inputVar == secondThing) {
    doSecondThing();
} else {
    doThirdThing();
}

Даже если он может быть записан как:

if (inputVar == thingOne) {
    doFirstThing();
    return;
}
if (inputVar == thingTwo) {
    doSecondThing();
    return;
}
doThingThree();
return;

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

Ответ 2

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

Ответ 3

Это шаблон, называемый Оговорка охраны. Идея состоит в том, чтобы все проверки вверх, чтобы уменьшить вложенные условия для повышения удобочитаемости.

Из ссылки:

double getPayAmount() {
    double result;
    if (_isDead) {
        result = deadAmount();
    } else {
        if (_isSeparated) {
            result = separatedAmount();
        } else {
            if (_isRetired) {
                result = retiredAmount();
            } else {
                result = normalPayAmount();
            }
        }
    }

    return result;
}

Используя предложение Guard, вы увидите этот результат:

double getPayAmount() {
    if (_isDead) return deadAmount();
    if (_isSeparated) return separatedAmount();
    if (_isRetired) return retiredAmount();

    return normalPayAmount();
};

Ответ 4

Вы увидите это повсюду:

if (condition) {
    return var;
}
// by nature, when execution reaches this point, condition can only be false,
// therefore, the else is unnecessary
return other_var;

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

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

0x00: test [condition]
0x01: if result of test was not true, goto [0x04]
0x02: push [var] onto stack
0x03: goto [0x05]
0x04: push [other_var] onto stack
0x05: return from subroutine

Код (опять же, это псевдокод, а не сборка) будет действовать точно так же для условного if/then/else.

Многие люди считают, что плохая и/или запутанная практика имеет несколько возможных точек выхода для функции, поскольку программист должен думать о каждом возможном пути через свой код. Другая практика заключается в следующем:

return (condition) ? var : other_var;

Это упрощает код и не создает никаких новых точек выхода.

Ответ 5

Я предпочитаю писать его вот так:

boolean containsSmiley(String s) {
    return s != null && s.contains(":)");
}

Ответ 6

Как и любая "дискуссия" о стилях кодирования, нет правильного ответа. Я предпочитаю применять эти соображения:

  • Работает ли код в ожидании во всех ситуациях. (Принцип наименьшего удивления)

  • Может ли следующий разработчик (я или кто-то еще) понять, что он делает и почему.

  • Насколько хрупким является код в отношении изменений.

  • Это просто, как и должно быть, и не более того. То есть нет над или под инженерией.

Как только я счастлив, что я удовлетворил вышеизложенное, остальные, как правило, просто падают в линию.

Ответ 7

else является избыточным. Кроме того, некоторые IDE (Eclipse) и инструменты анализа (возможно, FindBugs) могут отмечать это как предупреждение или ошибку, поэтому в этом случае программисты могут удалить его.

Ответ 8

Это религиозный аргумент, и в конце дня это не имеет значения. Я даже утверждаю, что первая форма более читаема в некоторых случаях. Если у вас есть большие куски кода в if-elseif-elseif-else, проще, на первый взгляд, посмотреть, что такое возврат по умолчанию.

if (s == null) {
    return false;
}
else if (s.Contains(":))")) {
    return true;
}
else if (s.Contains(":-(")) {
    return false;
}

return s.contains(":)");

Ответ 9

Оккамская бритва - это принцип, согласно которому "сущности не должны умножаться за пределы необходимости".

Ответ 10

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

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

Ответ 11

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

Ответ 12

Кто-то, возможно, уже это заметил, но я бы рекомендовал не использовать нулевые значения вообще, где ожидаются строки. Если вы действительно хотите проверить, чтобы кто-то пропускал нулевые значения, вы можете использовать утверждения (в dev time) или модульные тесты (развернуть):

boolean containsSmiley(String s) {
    assert s != null : "Quit passing null values, you moron.";
    return s.contains(":)");
}

Я перешел к общему правилу: Никогда. Когда-либо. передавать значения null, если только внешние вызовы API явно не запрашивают его. Второе: если внешний метод может возвращать нулевые значения, замените его на разумное ненулевое значение (например, пустую строку) или добавьте опрятную проверку. Я болею повторными проверками if (thing == null).

Но это немного оффтоп. Мне нравится помещать короткие условия в верхние и защитные предложения, удаляя elses, если поток программы подсказывает, что он никогда не доберется.

Ответ 13

Первая форма просто меньше подробностей - когда вы возвращаете значение, вы автоматически покидаете область действия функции, в которой вы находитесь, и возвращаетесь к вызывающей стороне, поэтому любой из последующих после этого кода будет выполняться только в том случае, если оператор IF не оценивать значение true и впоследствии возвращать что-либо.

Ответ 14

Я бы поспорил о удобочитаемости. Если вы сканируете экраны кода, пытаясь понять, что делает код, это визуальная подсказка разработчику.

... но это действительно не нужно, потому что мы все так хорошо комментируем наш код, так?:)

Ответ 15

По-моему, второй имеет больше смысла. Он служит скорее как действие по умолчанию, такое как переключатель. Если он не соответствует ни одному из других точек выхода, сделайте это. Тебе на самом деле больше не нужно. Я бы сказал, если вся функция будет только в том случае, если и elseif, то другой будет иметь смысл там, потому что это один гигант условный. Если в нем есть несколько условных выражений и других функций, то будет использоваться возврат по умолчанию в конце.

Ответ 16

Хотя наличие else правильное и в нем нет ничего плохого с точки зрения логики и работоспособности, мне нравится избегать начального момента WTF, когда функция не имеет оператора return вне области if/else.

Ответ 17

Как вы можете видеть, у разных людей разные мнения относительно читаемости. Некоторые люди думают, что меньшее количество строк кода делает код более читаемым. Другие считают, что симметрия второй формы делает ее более читаемой.

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

Ответ 18

Потому что в eclipse есть предупреждение (выключено по умолчанию), если в такой ситуации используется другое:;).

Ответ 19

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

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

Ответ 20

Я бы предпочел бы одну точку выхода по нескольким точкам обслуживания. Конечный результат может быть изменен (или украшен) в одной точке выхода, а не в n точках выхода.

Ответ 21

Вторая форма, если проще/короче. Это не всегда означает ясность. Я предлагаю вам делать то, что вы найдете наиболее ясным. Лично я бы написал.

static boolean containsSmiley(String s) { 
    return s != null && s.contains(":)"); 
} 

Ответ 22

Потому что это то же самое, что написать одно из следующего, которое приводит доказательства намерения программиста:

boolean containsSmiley(String s) {
    if (s == null)   // The curly braces are not even necessary as the if contains only one instruction.
        return false;

    return s.contains(":)");
}

Или даже это:

boolean constainsSMiley(String s) {
    return string.IsNullOrEmpty(s) ? false : s.Contains(":)");
}

Эти две формы:

  • Более элегантный;
  • Легче читать;
  • Leaner и swifter для программиста по чтению.