8

これに似た構造に出くわしたとき、私はいくつかの古いコードをリファクタリングしていました:

// function bar() returns a value
// if the value is an instance of customException class, terminate with error code
// else process the regular data

$foo = bar();
checkForException($foo) && exit($foo->errorCode());
process($foo);

奇妙に思えるかもしれませんが、これははるかに短いです

$foo=bar();
if(checkForException($foo)) {
    exit($foo->errorCode();
}
else {
    process($foo);
}

そして、いくらか読みやすくなります(少なくとも最初の驚きの後)

$foo=bar();
(checkForException($foo)) ? exit($foo->errorCode()) : process($foo);

コードが短いからといって必ずしも読みやすいコードであるとは限りませんが、これは上記の2つの「標準的な」方法の中間にあると思います。

言い換えれば、代わりに

if($foo) {
    bar();
}
else {
    // there is no real reason for this to exist, since 
    // I have nothing to write here, but I want to conform 
    // to the general coding practices and my coding OCD
}

簡単に書くことができます

$foo && bar();

では、これがあまり使用されていない理由は何ですか?「車輪の再発明をしないで、もっと読みやすいif / elseを書いてください。本当に短くしたいのなら、それが三項演算子の目的です」のように簡単にできますか?

編集:上記のコードは元のコードからすぐに派生したものであり、「短絡」コードの使用例にすぎないことに注意してください。可能であれば、コードの改善を提案することは控えてください。それは質問の望ましい結果ではなかったからです。

例2

userCheckedTheBox($user) && displayAppropriateInfo();
4

5 に答える 5

6

$foo && bar();コードの行数は少なくなりますが、読みにくくなります。通常、コードを理解しやすくすることは、総LoCを減らすことよりも重要です。複数のプログラマーがいる環境で作業していない場合でも、将来のある時点で戻ってコードを読む必要があり、おそらく、すべての行の背後にある論理的根拠を思い出せないでしょう。コード(イーグルソンの法則)。

一般に、これらの種類のステートメントの使用は、プログラマーの意図が完全に明確である場合にのみ制限する必要があります。私の意見では、条件をテストするコードと、同じステートメントでプログラムの現在の状態をアクティブに変更するコードを使用することは非常に悪い習慣です。

この種のコードの1つの許容可能な使用法は次のとおりです。

$isValidUser = $userName && usernameIsValid();

ここでは、演算子の両側が&&条件をテストしています。右側が関数を呼び出して、コードの可読性を損なうことはありません。

于 2013-03-24T21:49:02.983 に答える
3

エラーを表示するためにハッキングされたperlスクリプトで人気があったと私が信じている古い手法があります。擬似コード:

myFunction( ) || exitWithError( "Uh-oh" )

期限までにコーディングする場合、およびユーザーインターフェイスを優れたものにする必要がない場合は、エラーをすばやく回避する方法です。

このスタイルは、デフォルトのパラメーターのjavascriptでも人気があります。

function myfunction(foo) {
    foo = foo || 0;
    // note that a non-zero default won't work so well,
    // because the user could call the function with 0
}

およびヌルチェックの場合:

var bar = foo && foo.property;

if慣れれば、 /elseまたは。よりも非常に読みやすく、多くの場合直感的であることがわかり?:ます。ただし、意味がある場合にのみ使用してください。どこでもそれを使用すると、非常に混乱します。たとえば、あなたの例では、それを使用するべきではありません。個人的には、簡単なエラーチェックといくつかのデフォルト値に使用しています。大規模なプロジェクトでは、ほとんどの場合、エラーが発生したときにもっと多くのことをしたいので、そのような場合はこれを使用しないでください。

また、注意する必要があります。これは、短絡評価がある言語でのみ機能します(http://en.wikipedia.org/wiki/Short-circuit_evaluation)。そして時々andorは短絡しますが、そうでは&&あり||ません。

myfunction() or die("I'm melting!");書くのもとても満足です。

最後に、原則として空のelseブロックは、私がこれまでに見たことがない、または誰かが推奨するのを聞いたことがないものです。それは私には非常に無意味に思えます。あなたの例で最も読みやすいオプションは、非常に単純です。

if( $foo ) {
    bar( );
}
于 2013-03-24T22:23:37.320 に答える
1

エラーの場合は、実際の例外を使用する必要があります。

try {
  $foo = bar();
} catch(FooException $e) {
  exit($e->errorCode);
}
process($foo);

エラー処理については、ドキュメントを参照してください。

于 2013-03-24T21:55:11.723 に答える
1

そのコードが何をしていても、のインスタンスを返すCustomExceptionだけでは足りません。関数の定義を少し変更してみませんか。

function bar()
{
     $stuff = true;
     if ($stuff === true)
     {
         return 'Value on success';
     }
     //something went wrong:
     throw new CustomException('You messed up');
}
try
{//here's the outlandish try-catch block
     $foo = bar();
}
catch (CustomException $e)
{
    exit($e->message());//fugly exit call, work on this, too
}
//carry on here, no exception was thrown

また、その2番目の関数(checkForException($foo))を呼び出すのはばかげています。関数呼び出しは安価ですが、無料ではありません。CustomException関数が?のインスタンスを返したかどうかを知りたい。それを関数に変換するのではなく、を使用してくださいinstanceof。短絡を使用して文字数(したがって解析時間)を抑えると同時に、他のすべてのレベルでリソースを浪費することは、ハイパーマイリングコースでV8マスタングを使用するのと同じくらいばかげています。

于 2013-03-24T21:57:07.347 に答える
0

あなたの問題に対する別の可能な解決策:

$foo = bar();
!checkForException($foo) or exit($foo->errorCode);
process($foo);

しかし、それらの線に沿って何かを変更!checkForExceptionする方がよいでしょう。isNoException

于 2013-03-24T22:14:55.867 に答える