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());
}

现在,第二个选择几乎看起来不错,但是您必须记住有 11 个案例,这意味着有 11 个if (type in []),这是我想要的更多类型。

那么,飞镖有一些// //$FALL-THROUGH$我不知道的东西吗?

谢谢。

4

4 回答 4

27

Dart 规范提供了一种使用“继续”的方式让一个 switch case 继续到另一个 switch case:

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

飞镖语言之旅中,您的(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 继续”部分。

正如评论中所报告的那样,该错误现已修复,因此不再有效。因历史原因而保留。


此外,Lasse 的答案的简化是使用简单的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在 Dart 中有一个非空的 body 掉下来,这会引发错误。

除了非常简单的语句之外,我倾向于将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 回答