Почему “еще” редко используется после, “если x затем возвращаются”?

Этот метод:

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(":)");
}

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

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

60
задан Community 23 May 2017 в 11:54
поделиться

22 ответа

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

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;

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

69
ответ дан 24 November 2019 в 17:27
поделиться

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

static boolean containsSmiley(String s) { 
    return s != null && s.contains(":)"); 
} 
0
ответ дан 24 November 2019 в 17:27
поделиться

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

0
ответ дан 24 November 2019 в 17:27
поделиться

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

0
ответ дан 24 November 2019 в 17:27
поделиться

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

0
ответ дан 24 November 2019 в 17:27
поделиться

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

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

.
0
ответ дан 24 November 2019 в 17:27
поделиться

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

0
ответ дан 24 November 2019 в 17:27
поделиться

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

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

2
ответ дан 24 November 2019 в 17:27
поделиться

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

.
2
ответ дан 24 November 2019 в 17:27
поделиться

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

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

return s.contains(":)");
2
ответ дан 24 November 2019 в 17:27
поделиться

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

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

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

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

3
ответ дан 24 November 2019 в 17:27
поделиться

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

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

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

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

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

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

4
ответ дан 24 November 2019 в 17:27
поделиться

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

boolean containsSmiley(String s) {
    return s != null && s.contains(":)");
}
7
ответ дан 24 November 2019 в 17:27
поделиться

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

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;

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

8
ответ дан 24 November 2019 в 17:27
поделиться

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

По ссылке:

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

    return result;
}

Используя Guard Clause, вы увидите следующий результат:

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

    return normalPayAmount();
};
32
ответ дан 24 November 2019 в 17:27
поделиться

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

2
ответ дан 24 November 2019 в 17:27
поделиться

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

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(":)");
}

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

  1. Более элегантны;
  2. Легче читаются;
  3. Более просты и быстры для читающего программиста.
0
ответ дан 24 November 2019 в 17:27
поделиться

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

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

.
0
ответ дан 24 November 2019 в 17:27
поделиться

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

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

0
ответ дан 24 November 2019 в 17:27
поделиться

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

2
ответ дан 24 November 2019 в 17:27
поделиться

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

0
ответ дан 24 November 2019 в 17:27
поделиться

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

87
ответ дан 24 November 2019 в 17:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: