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

Return in for loop или out loop

Сегодня кто-то посещал меня из-за неправильного использования ключевого слова return в Java. Я написал простой цикл for для проверки того, что что-то находится в массиве. Предположим, что array является массивом длины n, это был мой код:

for (int i = 0; i < array.length; ++i) {
    if (array[i] == valueToFind) {
        return true;
    }
}
return false;

Теперь кто-то сказал мне, что это не очень хорошее программирование, потому что я использую оператор return внутри цикла, и это может привести к сбою сборки мусора. Поэтому лучше код будет:

int i = 0;
while (i < array.length && array[i] != valueToFind) {
    ++i;
}
return i != array.length;

Проблема в том, что я не могу придумать правильное объяснение того, почему первый цикл for не является хорошей практикой. Может кто-нибудь дать мне объяснение?

4b9b3361

Ответ 1

Теперь мне сказали, что это не очень хорошее программирование, потому что я использую оператор return внутри цикла, и это может привести к сбою сборки мусора.

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

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

Это гораздо менее полезно в Java: как только вы знаете, что вы должны вернуться (и каково должно быть возвращаемое значение), просто вернитесь. Таким образом, это проще читать - вам не нужно принимать какой-либо из остальных методов, чтобы выяснить, что еще произойдет (кроме блоков finally).

Ответ 2

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

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

Лично я бы написал:

Boolean retVal = false;
for(int i=0; i<array.length; ++i){
    if(array[i]==valueToFind) {
        retVal = true;
        break; //Break immediately helps if you are looking through a big array
    }
}
return retVal;

Ответ 3

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

Это не испортит сборку мусора!

Лучший способ сделать это - установить логическое значение, если вы хотите его послушать.

boolean flag = false;
for(int i=0; i<array.length; ++i){
    if(array[i] == valueToFind) {
        flag = true;
        break;
    }
}
return flag;

Ответ 4

Некоторые люди утверждают, что метод должен иметь одну точку выхода (например, только один return). Лично я считаю, что попытка придерживаться этого правила создает код, который труднее читать. В вашем примере, как только вы найдете то, что искали, немедленно верните его, это ясно и эффективно.

Цитирование вики C2:

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

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

Ответ 5

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

Один из моих преподавателей в Uni сказал нам, что не желательно иметь инструкции continue, return в любом цикле - for или while. Причиной этого является то, что при изучении кода не сразу становится ясно, будет ли выполняться полная длина цикла или будут задействованы return или continue.

См. Почему в этом примере существует непростая идея? для примера.

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

Что касается коллекции мусора - я понятия не имею, почему это будет проблемой.