最近のコードレビュー中に、default
で何もする必要がない場合でも、switch
ブロックが使用されているすべてのファイルにdefault
ケースを含めるように依頼されました。つまり、私はdefault
ケースを入れて何も書かなければならないということです。
これは正しいことですか?それはどのような目的に役立ちますか?
default
ステートメントが不要なケースは3つあるようです。
switch case
に入る値のセットが限られているため、他のケースは残りません。ただし、これは時間の経過とともに(意図的または偶発的に)変更される可能性があり、何かが変更された場合にdefault case
を使用すると、ログに記録したり、ユーザーに間違った値について警告したりできます。
switch case
がどこでどのように使用され、どの値が入力されるかがわかります。繰り返しになりますが、これは変更される可能性があり、追加の処理が必要になる場合があります。
その他の場合は、特別な処理は必要ありません。これが事実である場合、default case
を追加するように求められると思います。これは、受け入れられるコーディングスタイルであり、コードを読みやすくするためです。
最初の2つのケースは、仮定に基づいています。したがって(定期的なコードレビューがあるため、それほど小規模ではないチームで作業していると仮定すると)、これらの仮定を立てる余裕はありません。誰がコードを操作するのか、関数の呼び出し/コード内のメソッドの呼び出しを行うのかはわかりません。同様に、他の誰かのコードを操作する必要があるかもしれません。同じコーディングスタイルを使用すると、誰か(自分のコードを含む)のコードを扱いやすくなります。
これは正しいチオングですか?それはどのような目的に役立ちますか?
会社のコーディング標準では、すべてのswitch
ステートメントにデフォルトの大文字小文字の区別が必要になることは珍しくありません。その理由の1つは、読者がswitch
の終わりを見つけやすくすることです。別の、おそらくより良い理由は、条件が期待と一致しない場合にコードが何をすべきかを一瞬考えさせることです。要件の理由に関係なく、それが会社の標準である場合、気密な理由がない限り、それに従う必要があります。
switch
に考えられるすべての条件のケースが含まれていると思われる場合は、デフォルトのケースにassert
ステートメントを含めることをお勧めします。こうすることで、誰かがコードを変更し、不注意でswitch
がカバーしない条件を追加した場合、assert
にヒットし、コードのその部分に対処する必要があることに気付きます。
switch
が可能な条件のいくつかしかカバーしていないが、他の条件に対して特別なことをする必要がない場合は、デフォルトのケースを空のままにすることができます。その場合はコメントを追加して、デフォルトのケースが意図的に空であることを示すことをお勧めします。これは、ヒットした条件で実行する必要のある作業がないためです。
純粋な列挙型を「切り替える」と、デフォルトのフォールバックが危険になります。後で列挙型に値を追加すると、コンパイラーは新しい値がカバーされていないスイッチを強調表示します。そこにdefault句がある場合、コンパイラは沈黙し続け、見落とす可能性があります。
多くの点で、この質問はよくある質問と同じですelse
/else if
の最後にif
句が必要ですか?すべてのオプションをカバーするラダー。
答えは、構文的に言えば、そうではありません。しかし、そこには...
(少なくとも)2つの理由により、default
句が存在する可能性があります。
otherwise
があります。これらをソースコードに含めない理由はまったくありません。私の哲学は常に非常に単純です-2つのオプションの最悪のケースのシナリオを評価し、最も安全なものを選びます。空のelse
またはdefault
句の場合、最悪の場合のオプションは次のとおりです。
過激ですか?多分...しかし、私のソフトウェアはそれがうまくいかない場合、人々を殺す可能性があります。私はそのリスクを取らないほうがいい。
余談ですが、 MISRA-Cガイドライン {所属のプロファイルを参照} default
ごとにswitch
句を推奨しています
Javaは 'default'ステートメントを強制しませんが、コードに到達できない場合でも(現在)、常に(常に)1つ持つことは推奨です。これにはいくつかの理由があります。
到達不能なデフォルト句を持つことで、コードの読者に値を検討したことを示し、何をしているのかを知ることができます。たとえば、次のような変更も許可します。新しい列挙値が追加された場合、スイッチは黙って新しい値を無視してはなりません。代わりにそこで例外をスローするか、何か他のことを行うことができます。
渡された予期しない値(enumをオンに切り替えていない場合)をキャッチする-たとえば、期待した値よりも大きいまたは小さい場合があります。
「デフォルト」のアクションを処理するため-スイッチは特別な動作のためのものです。たとえば、変数はスイッチの外部で宣言されていても初期化されず、それぞれのケースで異なるものに初期化されます。この場合のデフォルトでは、デフォルト値に初期化できるため、スイッチの直後のコードでエラーが発生したり、例外がスローされたりしません。
デフォルトに何も入れないことを決定したとしても(例外、ロギングなど)、デフォルトが発生しないという事実を考慮したことを示すコメントであっても、コードを読みやすくするのに役立ちます。しかし、それは個人的な好みに帰着します。
また、それはあなたが使用している言語の哲学に依存することも付け加えておきます。たとえばErlangでは、「クラッシュさせる」ことが一般的なアプローチであり、デフォルトのケースを定義せず、case
ステートメントで、条件に合わない状況が発生した場合にエラーを発生させます。
すべてのケースを証明可能かつ永続的にカバーしていない限り、常にデフォルトを使用する必要があります。費用は一切かかりません。進化するプログラムでswitchステートメントを維持できなかった場合の保険になります。
他のケースを気にしないことを本当に確信している場合、デフォルト:break; //気にしないでくださいが、デフォルトのデフォルトはデフォルトのようなものでなければなりません:throw new Error( "unexpected value");
同様に、ドロップするつもりの効果にコメントを追加せずに、重要なケースコンストラクトを「ドロップスルー」しないでください。 Javaこれは設計段階でこれを間違っていました。