LoginSignup
37
25

More than 5 years have passed since last update.

すごいswitch文に出会った

Last updated at Posted at 2019-01-30

すごいswitch文に出会った

Javaのリファクタリング案件でこんなコードに出会いました。

switch ( cmd ) {
    case 0: 
        // 処理A
        // fall through
    case 1:
    case 2:
        // 処理B
        break;
    default:
        // 処理C
        break;
}

一見すると、 case 0処理A のみを実行するように見えますが、よくみると、 case 0 には break がないので、実は 処理B も実行されるんです!

最初は、 break の書き忘れかな?と思いましたが、どうやら仕様通りの挙動でした。

フォールスルーという技だった

このように、意図的に break を省略する記法を フォールスルー(fall through) と言うそうです。よく見たらコメントにも書いてありますね。

if 文で置き換えてみた

このフォールスルーは、とても面白いテクニックですが、誤読を招きやすく、バグの温床になると思ったので、残念ですが if 文に置き換えることにしました。

if ( cmd == 0 ) {
    // 処理A
}

if ( cmd <= 2 ) {
    // 処理B
} else {
    // 処理C
}

うーん、変更前の方がシンプルだったかな?微妙です。でも誤読の心配はなくなりました。

ただ、もし cmdString 型だったら、こんな書き方はできないですね。悩みます。

もっと良い書き方があれば、どなたか教えてください。

フォールスルーできる言語とできない言語

他の言語の事情が気になったので、軽く調べてみました。

switch 文で break を省略すると fallthrough になる言語

  • C
  • C++
  • JavaScript
  • PHP

switch 文で break を省略すると怒られる言語

  • C#
    • case 文の中で何もしない場合は、 break を省略できる。
    • goto で fallthrough のようなことはできる。

switch 文で明示的に fallthrough を指定する言語

  • Perl ( next を指定)
  • Swift ( fallthrough を指定)
  • Go ( fallthrough を指定)

switch 文に近い構文はあるが、 fallthrough はできない言語

  • Ruby ( case 文)
  • Scala ( match 文)
  • Kotlin ( when 文)

switch 文に相当する構文がない言語

  • Python

条件を満たす全てのブロックが実行される言語

  • PowerShell
    • fall through はできない。
    • 条件を満たす全てのブロックが実行される。
    • break を使えば、打ち切ることができる。

言語によって色々ですね!勉強になりました。

37
25
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
25