web-dev-qa-db-ja.com

If-else if-else over switchステートメントを使用する場合、またはその逆

一連のswitchステートメントに対してifブロックを使用する理由は何ですか?

switchステートメントは同じことをするようですが、入力に時間がかかります。

80
K2J

ほとんどの場合と同様に、コンテキストと概念的に正しい方法に基づいて、使用するものを選択する必要があります。スイッチは実際には「この変数値に基づいてこれらのいずれかを選択する」と言っていますが、ifステートメントは一連のブールチェックです。

例として、あなたがやっていた場合:

int value = // some value
if (value == 1) {
    doThis();
} else if (value == 2) {
    doThat();
} else {
    doTheOther();
}

これは、任意のテストではなく「値」の値に基づいてアクションの選択が行われていることをすぐに明らかにするため、スイッチとしてより適切に表されます。

また、スイッチとif-elsesを書いてOO言語を使用している場合は、それらを削除し、可能であれば同じ結果を得るためにポリモーフィズムを使用することを検討する必要があります。

最後に、入力にかかる時間が長くなることに関して、誰がそれを言ったのか覚えていないが、一度誰かが「あなたのタイピング速度は本当にあなたがコーディングする速さに影響するか?」 (言い換え)

74
tddmonkey

単一の変数の値を切り替える場合は、毎回スイッチを使用します。これが構成の目的です。

それ以外の場合は、複数のif-elseステートメントを使用してください。

45
Garry Shutler

可読性に関して:

私は通常、特にフォールスルーケースを許可する言語では、switchステートメントよりもif/elseコンストラクトを好みます。多くの場合、プロジェクトが古くなり、複数の開発者が関与するようになると、switchステートメントの構築に問題が発生します。

それら(ステートメント)が単純なもの以上になった場合、多くのプログラマーは怠け者になり、ステートメント全体を読んで理解する代わりに、単にケースにポップして、ステートメントに追加するケースをカバーします。

私は人のテストがすでにカバーされているため、switchステートメントでコードが繰り返される多くのケースを見てきましたが、単純な転倒ケースで十分でしたが、怠inessのために、スイッチを理解しようとする代わりに冗長コードを最後に追加する必要がありました。また、多くのケースが不完全に構築された悪夢のようなswitchステートメントを見てきました。すべてのロジックを単純に追おうとすると、多くのフォールスルーケースが全体に分散し、そうでない多くのケースは困難になります...私が話した最初の/冗長性の問題につながります。

理論的には、if/elseコンストラクトにも同じ問題が存在する可能性がありますが、実際にはこれはそれほど頻繁には発生しないようです。 if/elseコンストラクト内でテストされることが多い、より複雑な条件を理解する必要があるため、プログラマーは(推測だけで)もう少し注意深く読むことを余儀なくされるかもしれません。あなたが他の人が決して触れない可能性が高いことを知っているシンプルなものを書いていて、それをうまく構築できるなら、私はそれを投げることだと思います。その場合、あなたがそのコードを維持している可能性が高いため、より読みやすく、あなたにとって最も良いと感じるものはおそらく正しい答えです。

速度に関して:

Switchステートメントは、if-elseコンストラクトよりも高速に実行されることがよくあります(常にではありません)。 switchステートメントの可能な値は事前にレイアウトされているため、コンパイラはジャンプテーブルを作成することでパフォーマンスを最適化できます。 if/else構造のように各条件をテストする必要はありません(まあ、とにかく正しい条件が見つかるまで)。

ただし、これは常にそうとは限りません。たとえば、可能な値が1〜10の単純なスイッチを使用している場合がこれに該当します。追加する値を増やすにはジャンプテーブルを大きくする必要があり、スイッチの効率は低下します(if/elseではなく、比較的単純なswitchステートメントよりも効率が低下します)。また、値が非常に多様である場合(つまり、1から10の代わりに、1、1000、10000、100000など、100000000000までの10の可能な値がある場合)、スイッチは単純な場合よりも効率が低くなります。 。

お役に立てれば。

12
Allen Ratcliff

私は個人的には、ネストされたif-elsが非常に読みやすいので、ネストされたif-elseよりもswitchステートメントを見ることを好みます。スイッチは、状態を表示するための読みやすさの面でも優れています。

pacman ifs に関するこの投稿のコメントも参照してください。

1
SmacL

タイプするのに時間がかかるので物を避ける傾向は悪いことです。とはいえ、過度に冗長なものも読みにくいため、小さくシンプルなことが重要ですが、重要なのは書き込み可能性ではなく可読性です。簡潔な1行は、単純に適切にレイアウトされた3行または4行よりも読みにくい場合があります。

操作のロジックを最もよく説明する構成を使用します。

0
AnthonyWJones

単一の変数に2つ以上の条件がある場合は常にswitchを使用します。たとえば、平日を考えます。平日ごとに異なるアクションがある場合は、スイッチを使用する必要があります。

その他の状況(複数の変数または複雑なif節はIfすべきですが、それぞれをどこで使用するかについてのルールはありません).

0
Sergio

これは特定のケースに大きく依存します。できれば、if-elseがネストされている場合は、if-elsesよりもswitchを使用する必要があります。

問題は、いくらですか?

昨日、私は自分自身に同じ質問をしていた:

public enum ProgramType {
    NEW, OLD
}

if (progType == OLD) {
    // ...
} else if (progType == NEW) {
    // ...
}

if (progType == OLD) {
    // ...
} else {
    // ...
}

switch (progType) {
case OLD:
    // ...
    break;
case NEW:
    // ...
    break;
default:
    break;
}

この場合、1番目のifには不要な2番目のテストがあります。 2番目は、NEWを隠しているため、少し気分が悪いです。

読みやすいので、switchを選択しました。

0
bruno conde

異なる値を持つことができる単一の変数でのみ作業しているため、スイッチを使用することにしたとしましょう。これにより小さなswitchステートメント(2〜3件)が発生する場合は、それで問題ないと思います。それがあなたがより多くになると思われる場合は、代わりにポリモーフィズムを使用することをお勧めします。ここでは、AbstractFactoryパターンを使用して、スイッチで実行しようとしているアクションを実行するオブジェクトを作成できます。 switchいswitchステートメントは抽象化され、よりクリーンなコードになります。

0

私はよく、elseifを使用し、ケースインスタンス(言語が許可する場合)をドロップスルーすることは、匂いではないとしてもコードの臭いだと思っていました。

私にとっては、ネストされた(if/then/else)は通常elseifよりも良いことを反映し、相互に排他的なケース(多くの場合、属性の1つの組み合わせが別の組み合わせより優先される)、ケースまたは類似のものがより明確であることを発見しました2年後に読んでください。

Rexxで使用されているselectステートメントは、「ケース」をうまく行う方法(ドロップスルーなし)(愚かな例)の特に良い例だと思います。

Select
    When (Vehicle ¬= "Car") Then
        Name = "Red Bus"
    When (Colour == "Red") Then
        Name = "Ferrari"
    Otherwise
        Name = "Plain old other car"
    End

ああ、最適化がそれまでではない場合は、新しいコンパイラまたは言語を入手してください...

0

Switchステートメントは読みやすく、保守がはるかに簡単です。通常、より高速でエラーが発生しにくくなります。

0
Eldelshell