40

今日、誰かが私にreturnJava でのキーワードの不適切な使い方を教えてくれました。for何かが配列内にあることを検証するための単純なループを作成しました。arrayが length の配列であると仮定すると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 ループが適切な方法ではない理由を適切に説明できないことです。誰か説明してくれませんか?

4

6 に答える 6

80

ループ内で return ステートメントを使用すると、ガベージ コレクションが誤動作する可能性があるため、これはあまり良いプログラミングではないと誰かに言われました。

それは正しくありません。その人からの他のアドバイスには、ある程度の懐疑心を持って対処する必要があることを示唆しています。

すべてのリソースを自分で管理する必要がある言語では、「return ステートメントは 1 つだけにする」(より一般的には、終了点を 1 つだけにする) というマントラ重要です。これにより、すべてのクリーンアップ コードを 1 か所に確実に配置できます。

Java ではあまり役に立ちません。戻る必要があること (および戻り値がどうあるべきか) がわかったらすぐに戻ります。そうすれば、読みやすくなります - 他に何が起こるか (finallyブロック以外) を理解するために、メソッドの残りの部分を取り入れる必要はありません。

于 2012-05-29T13:37:42.623 に答える
10

ループ内で return ステートメントを使用すると、ガベージ コレクションが誤動作する可能性があるため、これはあまり良いプログラミングではないと誰かに言われました。

それはゴミの束です。クラスまたは他の場所でメソッドへの他の参照がない限り、メソッド内のすべてがクリーンアップされます (カプセル化が重要である理由)。経験則として、メソッドがどこで終了するかを把握しやすいという理由だけで、通常は 1 つの 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;
于 2012-05-29T13:35:48.290 に答える
4

どの関数でも単一の return ステートメントを使用することを推奨する方法論がすべての言語に存在します。特定のコードでは不可能かもしれませんが、それを目指して努力する人もいますが、コードがより複雑になる可能性があります (コードの行数が増えるなど)。フロー)。

これにより、ガベージコレクションが台無しになることはありません!!

彼の話を聞きたい場合は、ブール値を設定することをお勧めします。

boolean flag = false;
for(int i=0; i<array.length; ++i){
    if(array[i] == valueToFind) {
        flag = true;
        break;
    }
}
return flag;
于 2012-05-29T13:36:19.707 に答える
3

一部の人々は、メソッドには単一の終了ポイント (たとえば、1 つのみreturn) が必要であると主張します。個人的には、そのルールを守ろうとすると、コードが読みにくくなると思います。あなたの例では、探していたものを見つけたらすぐに返します。それは明確で効率的です。

C2 wiki の引用:

関数に単一の入り口と単一の出口を持つことの本来の意味は、規律のない goto SpaghettiCode とは対照的に、StructuredProgramming の元の定義の一部であり、それに基づいて明確な数学的分析を可能にしたことです。

構造化プログラミングが勝利を収めて久しい今、そのことを特に気にする人は誰もいません。ページの残りの部分は、構造化プログラミング構造の数学的分析ではなく、主にベスト プラクティスや美学などに関するものです。

于 2012-05-29T13:38:18.503 に答える
2

どちらの場合でも、コードは有効です (つまり、コンパイルして実行できます)。

Uni での私の講師の 1 人は、ループ内に , ステートメントを含めることは望ましくないと言いcontinueましreturnた。この理由は、コードを調べたときに、ループの全長が実行されるのか、それとも orが有効になるのかがすぐにはわからないためです。forwhilereturncontinue

なぜループ内で続行するのが悪い考えなのかを参照してください。たとえば。

心に留めておくべき重要なポイントは、このような単純なシナリオでは (IMO) 問題ではないということですが、戻り値を決定する複雑なロジックがある場合、代わりに単一の return ステートメントがある場合、コードは「一般的に」読みやすくなります。いくつかの。

ガベージ コレクションに関しては、なぜこれが問題になるのかわかりません。

于 2012-05-29T13:40:33.697 に答える