web-dev-qa-db-ja.com

PHPコーディングスタイルが戻る;スイッチ/ケース内

チームに新しいコーディングスタイルガイドラインを実装しようとしています。phpコードスニファーは、「break」が見つからない場合にswitch caseステートメントに警告を出力します。

switch ($foo) {   
    case 1:
      return 1;   
    case 2:
      return 2;   
   default:
       return 3; 
}

使用する理由はありますか?

   switch ($foo) {
       case 1:
         return 1;
         break;
   }

?休憩に到達することはありませんか?

48
opHASnoNAME

breakからreturnを使用する場合は、switchを省略することは完全に有効です。

しかし、明示的なbreaksをすべてのcasedefensive programming practiseとして追加するのはかなり一般的な方法です。

switch ($foo) {
    case 1:
        return 1;
        break;

    case 2:
        return 2;
        break;
}

後からcase 1のコードを変更してreturnステートメントを削除した場合、breakを追加するのを忘れることがあります。

これにより、プログラムフローが誤ってcase 2に落ちてしまいます。

switch ($foo) {
    case 1:
        somethingDifferent();

    case 2:
        return 2;
        break;
}

Caseステートメントを抜けることは少し珍しいので、コードが意図的であることを示すためにコードにコメントを追加する必要があります。

switch ($foo) {
    case 1:
        somethingDifferentAndWeWantToDoCase2AsWell();
        // fallthrough

    case 2:
        return 2;
        break;
}

多くの防御的なプログラミングの慣行と同様に、コードが肥大化してコードが混乱し、読みにくくなる可能性があるかどうかのバランスを取る必要があります。

79
John Carter

「phpコードスニファーが警告を出力している」場合は、より優れたコードスニファーを取得し、最後のPHP安定バージョンを使用することを忘れないでください。もちろん、breakafter returnですが、まったく読み込まれないため、意味がありません。コードは問題ありません。

これを見てください:

$fun = function(int $argument): string {
    switch ($argument) {
        case 1:
            return "one";
        case 2:
            return "two";
        default:
            return "more than two";
    }
};
$str = $fun(4); // return "more than two"

私の意見では、これはよりシンプルで優れています:少ない行=>維持するコードが少ない:-)

4
Chemaclass

あなたの質問に答えるために、いいえ、何もしないものを持っている正当な理由はありません。このように考えてください。returnの代わりにbreakの後にある「忘れないでください」というコメントも同じ効果があります-なし。そして、そのように言えば、ばかげているように聞こえますか?

後で使用するために変数を設定する必要がない限り、あなたが持っているアプローチは完全にうまくいくことを提案します。私はコードを見てから2秒以内にコードの意図を知っていました。 breakがあると混乱が生じます。

すべてに合うサイズはありません。正しいアプローチは、シナリオに適合する方に依存します。それぞれのcaseに変数を設定し、breakを使用するのが正しい方法かもしれません。



回答で行われた他の提案に関するいくつかの観察:

1)breakの後にreturnがないと、後でコードが変更された場合に問題が発生する可能性があることを意味します

可能な限り、コードは明示的で、読みやすく明確でなければなりません。また、将来の変更を容易にする方法でコーディングすることもできます。しかし、switchのような単純なものでは問題はなく、後でcaseをリ​​ファクタリングしてreturnまたはbreakを追加または削除するためのセーフティネットは必要ありません。

実際、returnを削除し、「breakがなかったことに気付かなかった」場合、それは悪い間違いであり、コーディングのどの部分でも行うことができます。落とし穴チェックはあなたをそこから救いませんそして、将来の可能性については非常に慎重にコーディングする必要があります。潜在的な可能性は決して発生しないか、他の何かが発生する可能性があります。

同じように、これは将来の変更に対するセーフティネットであると主張されました-returnを削除し、削除する必要があるときに誤ってそのセーフティネットbreakに残した場合はどうなりますか?

このswitchステートメントが生死のシナリオ、本当に深刻なコードであったとしても、復帰後に「無意味な」ブレークを追加することに反対するでしょう。コードの作業をしている人が自分のやっていることを知っていることを確認してください。コードは十分な目でレビューされ、完全にテストされました。
それがそれほど深刻だった場合、ずさんな開発者を捕まえるために提案されたセーフティネットよりも適切な追加のチェックがあるでしょう。

復帰後の破損がセーフティネットを追加すると主張することは、適切にコーディングまたはテストしていないことを意味します。これが便利だと思われるセーフティネットである場合、より深刻な可能性のある場所のコードに多数のバグがある可能性があります。

「Defensive Programming」のwiki記事はリンクされていましたが、ここでは関係ありません。

防御的プログラミングは、予期せぬ状況下でソフトウェアの継続的な機能を保証することを目的とした防御設計の一形態です。

セーフティネットbreakを残すことは、予期しない状況のシナリオでも、防御的なプログラミングでもありません。それはコーディングが悪いだけです、何かを変更するときに正しくコーディングしない場合に備えて、バックアップコードでコードを散らかすことはできません。それはコーディングに対するこのような悪いアプローチです。 「誰かが削除された場合、それは動作しません」という議論は、ケースvarにタイプミスがあるか、ケースを書くのを忘れるかもしれません...

returnは戻ります。戻り値の失敗を避けるために「防御的に」コーディングしないでください。これはPHPが壊れていることを意味し、コードをセーフティネットで埋めてそれを満たそうとはしません。それはあなたがより高いレベルに持っているものです。

2)breakreturnが明示的に保持した後

しかし、それは明らかに間違っています。 returnが返されるため、ブレークは発生しません。私にとっては、意図を逃したのかどうか疑問に思っているスクラッチヘッドタイムです-何がwillが起こるかが明確である限りではありませんが、私はそれを作ることを熟考する瞬間があります確かに私は何かを見逃していない。

同じreturnbreakを配置してからcaseを配置することは無効でもエラーでもありませんが、breakが何もしないのでまったく意味がありません。それは論理的ではないので、見て、維持し、理解する必要がある無意味なコードです。

explicitが核となる目標である場合andbreakの後にreturnを指定することは意味がないので、それが意味がないので、私はそれを言うでしょうd変数とbreakを設定し、スイッチからブレークした後に変数を返す方が適切です。
@ RageZの回答のように https://stackoverflow.com/a/1437476/2632129

3)変数を設定し、switchステートメントの完了後に戻る

このアプローチには何の問題もありませんが、変数に値を保存する理由がない場合(後で使用する場合など)は、他のことをするためにぶらぶらする必要がないときにすぐに戻ることをお勧めします。

これは明確な意図を示しています。ケースが一致するとすぐに値を返します。

3
James

上記のswitchステートメントについては、以下のコードに従ってください:

$result = 3; // for default case
switch ($foo) {   
    case 1:
      $result = 1;
      break;  
    case 2:
      $result = 2;
      break;    
   default:
      // do nothing
}
return $result;

エラーが発生することはなく、コードも概念に適しています。

3
Lavkush