web-dev-qa-db-ja.com

変数を再利用する必要がありますか?

変数を再利用する必要がありますか?

多くのベストプラクティスでは、これを行うべきではないと述べていますが、後で、別の開発者がコードをデバッグしていて、3つの変数が似ている場合、唯一の違いは、それらがコードの別の場所に作成されることです。混乱した。ユニットテストはこの良い例です。

ただし、私はdoベストプラクティスがほとんどの場合それに反対することを知っています。たとえば、メソッドのパラメーターを「オーバーライド」しないように言います。

ベストプラクティスは、以前の変数をnullにすることです(Java変数にnullを割り当てるときに警告を表示するソナーがあり、それを行う必要はありません) Java 6.以降、ガベージコレクターを呼び出す必要があります。オフにする警告を常に制御することはできません。ほとんどの場合、デフォルトはオンです。)

60
IAdapter

メソッドが長く、複数のタスクを順番に実行している場合にのみ、問題が発生します。これにより、コード自体を理解する(したがって維持する)ことが難しくなります。変数を再利用すると、さらにリスクの要素が追加され、コードの追跡がさらに難しくなり、エラーが発生しやすくなります。

IMOのベストプラクティスは、1つのことだけを行う十分に短い方法を使用して、問題全体を排除することです。

130
Péter Török

メソッドでの変数の再利用は、それをリファクタリング/分割する必要があるという強い兆候です。

だから、私の答えは、それらを再利用してはいけないということです。なぜなら、それを行うと、後でリファクタリングするのがはるかに難しくなるからです。

49

場合によります。

一部の変数は、特定の種類のデータを保持する目的で正確に作成される場合があり、関数の実行中に変更される可能性があります。ここに戻りコードが思い浮かびます、例えば:

void my_function() {
    HRESULT errorcode;
    errorcode = ::SomeWindowsApiFunction();
    if (FAILED(errorcode)) { /* handle error */ }
    errorcode = ::AnotherWindowsApiFunction();
    if (FAILED(errorcode)) { /* handle error */ }
}

変数名により、この変数が何を格納するかが非常に明確になります。私はこれのような他のユースケースが可能であると思います。ここで、変数は概念的には関数の過程で非常に類似したものの異なるインスタンスによって論理的に使用されるコンテナーです。

ただし、一般に、これは、コードを読む可能性のある読者に絶対的に明らかな状況でのみ行う必要があります。コードの読みやすさを考慮せずに極端な最適化を除いて、型が適合するという理由だけで変数を再利用するべきではありません。

これはすべて、基本的に変数の名前付けに関する優れた慣例に基づいています。名前はそれ自体が語るべきです。すべての再利用の正確な目的を短い名前で表すことが難しい場合は、個別の変数を使用することをお勧めします。

19
Felix Dombek

(特に単体テストで)変数を再利用しない最大の理由は、テストとデバッグが難しい不要なコードパスが導入されるためです。優れたユニットテストは他のテストから独立している必要があり、ユニットテストフィクスチャでクラス(インスタンス)レベルの変数を再利用する場合は、各テストの前にその状態をアサートする必要があります。優れた単体テストでは、欠陥も分離されるため、理論的には、各テストケース(メソッド)はテスト中のシステムに対して1つの動作のみをアサートする必要があります。テストメソッドがこのように記述されている場合、メソッドレベルの変数を再利用する必要や利点はほとんどありません。最後に、クロージャーと非同期処理をサポートする言語では、メソッド全体で変数を再利用している場合、何が起こっているのかを推測することは本当に困難です。

15
sbrenton

別の変数を使用する必要があります。同僚が混乱するのではないかと心配している場合は、その役割を明確に表す名前を付けてください。
変数を再利用することは、将来混乱の原因となる可能性があります。今それを片付ける方が良いです。
場合によっては、同じ変数名を再利用できます。たとえば、単純なカウントループのiです。これらの場合、もちろん変数が独自のスコープ内にあることを確認する必要があります。

編集:変数の再利用は、 単一の責任の原則 に違反していることを示す場合があります。再利用された変数が同じロールで使用されているかどうかを確認してください。そうである場合、それはまったく再利用されない可能性があります(ただし、上記の変数のスコープを制限するために、2つの異なる変数を使用することが望ましい場合があります)。さまざまな役割で使用されている場合、SRP違反が発生しています。

他の回答によるすばらしいアドバイスに関係なく、変数を再利用したい状況が1つあります。コンパイラーが助けを必要とするときです。

場合によっては、特定のレジスターに割り当てられた変数がコードの次の部分で使用されなくなったことをコンパイラーが十分に認識できないことがあります。したがって、次の変数に対して理論的に空きのレジスタを再利用することはなく、生成されたコードは最適ではない可能性があります。

現在の主流コンパイラーがこの状況を正しくキャッチできないことは知らないことに注意してください。コンパイラーが最適ではないコードを生成しているという事実を知らない限り、決してこれを行わないでください。カスタムコンパイラーを備えた特別な組み込みシステム用にコンパイルしている場合でも、この問題が発生する可能性があります。

4

私はノーと言うでしょう。

このシナリオについて考えてみましょう。プログラムがクラッシュし、コアダンプを調べて何が起こったのかを調べる必要があります...違いがわかりますか? ;-)

2
fortran

いいえ、マシンが実行しているコード(...アセンブリコード)を改善しているわけではありません。コンパイラーが変数に使用するメモリーをコンパイラーに再利用します。多くの場合、それはレジスターになり、再利用しても何も購入しませんでした。コードを読みやすくすることに焦点を当てます。

2
Rawbert

場合によります。動的言語では、型が変数ではなく値に存在する場合、たとえば文字列である関数への適切な名前の引数があったとします。私はアルゴリズムの変更により、整数として解釈された後は常にそれが使用されることを意味し、最初のドラフトとして、

scrote = int(scrote)

しかし、最終的には、関数に送信されるタイプを変更して、パラメータータイプの変更に注目します。

0
Paddy3118

まず、開発環境を確認します。同じ名前の異なるスコープに5つの変数があるためにデバッグに問題があり、デバッガーがこれらの変数のどれが必要な変数であるかを表示しない場合は、同じ名前の5つの変数を使用しないでください。これを行うには、2つの方法があります。1つの変数を使用するか、5つの異なる名前を使用します。

デバッガによっては、多くの変数を持つ関数をデバッグするのが面倒になる場合もあります。 20変数の関数が16変数の関数よりもデバッグが難しい場合は、5変数を1変数に置き換えることを検討してください。 (「考慮しなければならない」は「常にすべき」と同じではありません)。

Ok変数が常に同じ目的を持っている限り、1つの変数を複数の場所で使用することです。たとえば、10個の関数呼び出しがエラーコードを返し、呼び出しごとにすぐに処理される場合、 10ではなく、1つの変数を使用します。ただし、まったく異なるものに同じ変数を使用しないでください。顧客名に「name」を使用し、10行後に会社名に同じ変数を使用するなど、それは悪いことです。さらに悪いことに、顧客名に「customerName」を使用し、10行後に会社名に同じ変数「customerName」を使用しています。

重要なことに、何も鉄則ではありません。すべてに長所と短所があります。 「ベストプラクティス」が1つのことを示唆しており、特定の状況でそれが悪いアイデアだと言う理由がある場合は、それを行わないでください。

0
gnasher729

まず、開発環境を確認します。同じ名前の異なるスコープに5つの変数があるためにデバッグに問題があり、デバッガーがこれらの変数のどれが必要な変数であるかを表示しない場合は、同じ名前の5つの変数を使用しないでください。これを行うには、2つの方法があります。1つの変数を使用するか、5つの異なる名前を使用します。

デバッガによっては、多くの変数を持つ関数をデバッグするのが面倒になる場合もあります。 20変数の関数が16変数の関数よりもデバッグが難しい場合は、5変数を1変数に置き換えることを検討してください。 (「考慮しなければならない」は「常にすべき」と同じではありません)。

Ok変数が常に同じ目的を持っている限り、1つの変数を複数の場所で使用することです。たとえば、10個の関数呼び出しがエラーコードを返し、呼び出しごとにすぐに処理される場合、 10ではなく1つの変数を使用します。これには1つの問題があります。通常、初期化されていない変数を使用するとコンパイラーから通知されます。ただし、ここで、呼び出し6の後にエラーコードを読み取っても、変数は実際には変更されていません呼び出し5の後、コンパイラーが警告することなく、役に立たないデータを取得します変数が初期化されているため、役に立たなくなったデータが含まれています。

重要なことに、何も鉄則ではありません。すべてに長所と短所があります。 「ベストプラクティス」が1つのことを示唆しており、特定の状況でそれが悪いアイデアだと言う理由がある場合は、それを行わないでください。

0
gnasher729