web-dev-qa-db-ja.com

異なるスコープで同じ変数名を使用するのは悪いフォームですか?

近くのレキシカルスコープで同様の操作が行われるいくつかの基本的なコードがあるとします。いくつかの簡単な疑似コードを例にとります:

variable = "foo"
# Do something with variable
if (True) {
    variable = "bar"
    # Do something else with variable
}
for i in range 1..100 {
    variable = i
    # Do another thing with variable
}

それぞれのスコープで、変数は異なるが類似したタスクに使用されるため、「変数」という名前が適切です。この場合の命名のベストプラクティスは何ですか?毎回「変数」という名前を使用する必要がありますか? 「variable1」、「variable2」などの名前を増やしますか?それとも完全に別のものですか?

1
jkeuhlen

問題の変数が両方の関数で同じものを表す場合、なぜそれが問題になるのかわかりません。 variableを任意に使用して「関数内で何かを実行できるすべての変数」を意味している場合は、問題があります。変数は、それらが使用されるコンテキストで名前を付けます。

3
Lawrence Aiello

ここでは、まったく異なる2つのことが行われています:variable reuseおよびvariable name reuse(再宣言。)サンプルの疑似コードでは、2つのケースのどちらを参照しているかが明確にならないため、両方について説明します。

これは変数の再利用です。

int i = 5;
for( ;; )
{
    i = 3;
    ...
}

これは変数名の再利用です:

int i = 5;
for( ;; )
{
    int i = 3;
    ...
}

変数の再利用は非常に悪いことであり、スパゲッティコードにつながるため、絶対に回避する必要があります。コードはforループの後に1日追加され、i5、そうでないことを知るのは非常にショックになるかもしれません。このコードを読む人々は、ループの後で新しい値を使用するためにiの値を置き換えると想定します。まともなコンパイラーは、これを行うと「変数の再利用」または「変数のスコープが広すぎます」という警告を表示しますが、常にそれを検出できるとは限りません(forループの場合、 、あなたは故意にそれをしているかもしれないので、)あなたの運をプッシュしないことが最善です。

変数名の再利用は完全に適切であり、特定のシナリオでは実際には望ましいです。たとえば、変数名の再利用により、forループ内で外側のスコープiが誤って参照されないことが保証されます。これは、外側のスコープが再定義されたため、アクセスできないためです。 (残念ながら、C#はそれを好みませんが、他のほとんどの言語では問題ありません。)

この問題について同僚と議論するときに議論をするために、stackoverflowで正確にこの質問をしている可能性があるので、「同僚の言うことによって良いか悪いか」には答えません。

3
Mike Nakis

変数がi, count, sumのように単純で明確なものである場合は、先に進んで再利用してください。

変数がcalculatedResultのようにメソッドの中心である場合、または一連のif/elseブロック(またはreturn calculatedResultで終わるすべてのブロック)にいる場合は、それを再利用します。

ただし、ブロックが相互に排他的ではなく、制御が一方から他方へ流れる場合、同じ変数名を再利用しない方が明確な場合があります。たとえば、一連のSQLクエリを実行している場合、私は行くかもしれません(Java風の構文)

if (theyCareAboutPeople) {
   peopleQuery = "SELECT * FROM people WHERE blah blah...";
   ResultSet people = mySqlDriver.execute(peopleQuery);
   // do something with people
}
if (theyCareAboutAges) {
   ageQuery = "SELECT * FROM ages WHERE blah blah...";
   ResultSet ages= mySqlDriver.execute(ageQuery );
   // do something with ages
}

すべてのクエリ「query」とすべての結果「result」を呼び出す代わりに、「peopleQuery」と「ages」のような意味のある名前を使用したことに注意してください。 IMO、これはややより明確ですが、YMMVです。

1
user949300

変数を再利用することは悪いことです。なぜなら、通常は初期化されていない変数などについて警告するコンパイラは警告を表示できないためです。2回目の使用時に、変数は初期化されるためです。

変数名の再利用は、通常は問題ありません。

外部スコープで別の変数と同じ名前の変数を作成すると、コンパイラ警告が表示される場合があります。混乱を招き、エラーが発生しやすくなるためです。警告が表示されるかどうかに関係なく、回避してください。

同じ名前の変数が12個あり、現在どの変数を使用しているかを判断できないデバッガーで問題が発生する場合があります。これはデバッガーの問題であり、修正する必要がありますが、この状況に遭遇した場合は、よりデバッガーに適したコードを作成することを選択できます。

0
gnasher729

特異性-エンジンの変数タイミングなど、特定の変数を参照しない限り、variableという名前の変数を使用しないでください。しないでください。

特定のコンテキストで:

特定のコンテキストで変数名を別の目的に再利用しないでください。関数では、変数= 'foo'を文字列として使用しないでください。その後、関数で変数をループ内の数値インデックスにします。これは悪い習慣であり、大きな意味であなたに噛み付きます。

同じ汎用的な目的で特定のコンテキストで変数名を再利用できますが、混乱を避けるために新しい変数の使用を検討してください。

var i, j, myarray = [];
for( i = 0; i < 100; i++){
//
   mayarray.Push[ i ];
}

for( j = 0; j < 1000; j++){
   // something with j
}

新しい変数jを使用する代わりに、技術的に2番目のループにiを再利用できますが、この場合、コードの読み取りに混乱を招き、後でバグが発生する可能性があるため、再利用は避けます。

同じコンテキスト外

ループインデックスにiのような共通の変数名を再利用します。これは良い習慣であり、同じコンテキストにない限り読みやすさが向上します。

PartNumberなどの非ジェネリック変数名の再利用を検討している場合は、その再利用を、変数の他の用途と同じ論理的なものをコード内で参照する場所に制限してください。そうしないと、コードが混乱する可能性があります。

アプリケーションには、操作しているデータを示すスキーマが内部にあります。そのスキーマを変数名にマップし、一般的な目的で一般的な変数名を使用し、変数を再利用するためのコンテキストに注意してください。

0
Robert Munn