17

今日から Dart の学習を始めましたが、私の Google スキルでは見つけにくいものに出会いました。

空でないケースでフォールスルーを行うにはどうすればよいですか?

私の使用例は次のとおりです。私は sprintf の実装を書いています (dart にはこれもありません)。変数の型を解析する場合、たとえば、"%x" と "%X" を比較することができます。大文字の型は、出力が大文字であることをフォーマッタに伝えます。

準擬似コードは次のようになります。

bool is_upper = false;
switch (getType()) {
    case 'X':
      is_upper = true;
    case 'x':
      return formatHex(is_upper);
}

これを行うことを考えることができる他の方法は、次のいずれかになります

1:

switch (getType()) {
  case 'X': case 'x':
    return formatHex('X' == getType());
}

2:

var type = getType();
if (type in ['x', 'X']) {
   return formatHex('X' == getType());
}

さて、2 番目の選択肢はほとんど問題ないように見えますが、11 のケースがあることを覚えておく必要があります。これは、 eleven を持つことを意味しif (type in [])ます。

それで、ダーツには// //$FALL-THROUGH$私が知らないものがありますか?

ありがとう。

4

4 に答える 4

27

Dart仕様は、スイッチケースが「続行」を使用して別のスイッチケースに続行する方法を提供します。

switch (x) {
  case 42: print("hello");
           continue world;
  case 37: print("goodbye");
           break;
  world:  // This is a label on the switch case.
  case 87: print("world");
}

これはVMで機能しますが、残念ながら、dart2jsスイッチの実装はまだその機能をサポートしていません。

于 2012-09-28T14:18:24.880 に答える
7

dart language tourから、(2) の例は正しいはずです。

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':     // Empty case falls through.
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeClose();
    break;
}

次のようなことをしようとするとエラーになります

var command = 'OPEN';
switch (command) {

  case 'OPEN':
    executeOpen();
    // ERROR: Missing break causes an exception to be thrown!!

  case 'CLOSED':
    executeClose();
    break;
}
于 2012-09-23T18:46:26.373 に答える
6

編集: これは、Dart の実装のバグが原因でのみ機能したようです。Dart 1.x 言語仕様のセクション「17.15 続行」を参照してください。

コメントで報告されているように、バグは修正されたため、これは機能しなくなりました。歴史的な理由から保持します。


また、ラッセの答えを単純化するには、次のように単純なcontinue;代わりに使用することcontinue <label>;です。

bool is_upper = false;
switch (getType()) {
    case 'X':
      is_upper = true;
      continue;
    case 'x':
      return formatHex(is_upper);
}
于 2015-10-05T11:33:54.530 に答える
3

ダートに空でないcaseボディが落ちることはできません。これによりエラーが発生します。

私が非常に単純なステートメント以外で行う傾向があるのは、switchすべての一般的なコードを関数にリファクタリングすることです。これにより、このマルチレベルの制御フローswitch自体がなくなります。

言い換えれば、次のようなものです。

switch (getType()) {
    case 'X':
        return formatHex(true);
    case 'x':
        return formatHex(false);
}

フォールスルーが必要な理由はありません。caseセクション内のアクションを別のセクションの最後でまとめて実行できる場合に便利ですが、この方法では、フォールスルーやステートメントを複雑caseにすることなくそれを実行できます。switch

また、最後にtotoに含まれていない一般的なアクションがあるより複雑なケースを処理することもできます。たとえば、セクションの最初または途中で何かをしたい場合がありますcase。一般的な関数を呼び出すと、それを十分に処理できます。

switch (getType()) {
    case 'X':
        doSomethingOnlyForUpperCase();
        doSomethingCommon();
        doSomethingElseOnlyForUpperCase();
        return formatHex(true);
    case 'x':
        doSomethingCommon();
        return formatHex(false);
}

私は実際、この種の空でないフォールスルーをサポートする言語(Cなど)に対してもこれを行います。これは、読みやすさと保守性に役立つと信じているからです。

于 2012-09-23T06:18:44.627 に答える