【问题标题】:How can I use a switch statement when passing an argument to a function? (dart)将参数传递给函数时如何使用 switch 语句? (镖)
【发布时间】:2021-12-05 10:37:18
【问题描述】:

在 Dart 中,可以使用switch statements 而不是很长的if-then-else

var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    executeClosed();
    break;
  case 'OPEN':
    executeOpen();
    break;
  default:
    executeUnknown();
}

但有时我们只想根据条件提供一个值。例如,在函数调用、类实例化或设置变量的值等内部。

例如

// Doesn't work, but wish it did
MakeNametag(
   adjustFontSize: switch(status) {
     case 'young' : return 'large';
     case 'old' : return 'largest';
     default: return 'normal';
    } //end switch
  }
);

如果您只有两种选择,一种可以使用conditional operator(有时称为三元运算符)

// Works
MakeNametag(
  adjustFontSize: ['old','young'].contains(status) ? 'larger' : 'normal');

(javascript有相同的操作符和问题)

【问题讨论】:

  • 你问的是 Dart 还是 JavaScript?选择一个。
  • 编辑标题和标签以专注于 Dart。三元运算符在两者中的工作方式相似,但我意识到答案可能因语言而异。

标签: dart chaining ternary


【解决方案1】:

在 Dart 中,switch 只是一个语句,不是一个表达式,所以不能作为参数使用,它必须是一个表达式,并且有一个值。

你可以做的是定义一个辅助函数:

String fontSizeFromAge(String age) {
  switch (age) {
    case 'young' : return 'large';
    case 'old' : return 'largest';
    default: return 'normal';
  }
}
MakeNametag(
  adjustFontSize: nameTagFromAge(status)
);

或者,如果您坚持使用该值的开关,则可以在此时编写并调用该函数:

MakeNametag(
  adjustFontSize: () {
      switch (status) {
        case 'young' : return 'large';
        case 'old' : return 'largest';
        default: return 'normal';
  }(),
);

(){ ... }() 语法是一个零参数函数字面量 () { ... },它会立即使用零参数 ... () 调用。这是在 Dart 中将语句放入表达式的唯一真正方法。

【讨论】:

    【解决方案2】:

    通常情况下,您可以定义一个映射文字并立即在其中下标[],而不是简单的switch 语句。使用 if null 运算符 ?? 处理 default 情况。

    MakeNametag(adjustFont: {'young': 'large', 'old': 'largest'}[status] ?? 'normal');
    

    通常您还可以将地图文字设为const 以提高性能。

    MakeNametag(adjustFont: const {'young': 'large', 'old': 'largest'}[status] ?? 'normal');
    

    【讨论】:

      【解决方案3】:

      是的。我在玩语法时发现了它,我认为以下看起来比大多数其他方式更好。可以链接三元运算符。

      以下是在传递给函数的参数中使用“switch”思想的示例:

      void main() {
        int a=2;
        print(
          a==1 ? "s" :
          a==2 ? "t" :
          a==3 ? 'u' :
          a==4 ? 'v' :
          a==5 ? 'w' :
          'x'
        ); 
      }
      

      使用问题中的示例,这就是上面示例的样子。

      MakeNametag(
         adjustFont: 
           status=='young' ?  'large' :
           status=='old' ?  'largest' :
           status=='funky' ?  'wavy' :
           status=='microsoft' ?  'timesNewRoman' :     
           status=='google' ?  'roboto' :
           'normal',
        }
      );
      

      还有很多其他方法可以做到这一点,例如创建一个类或使用Map 对象并根据键查找值。但这是我所知道的最紧凑的方式。

      PS。我之所以写这篇文章是因为我发现很难找到如何称呼这种模式的答案。

      【讨论】:

      • 地图对象方法肯定比嵌套三元组更紧凑。 MakeNametag(adjustFont: {'young': 'large', 'old': 'largest'}[status] ?? 'normal');MakeNametag(adjustFont: status == 'young' ? 'large' : status == 'old' ? 'largest' : 'normal');。最大的区别在于映射字面量方法您只需要引用一次status 变量,而对于嵌套三元组,您必须为每个选项编写一个status ==
      • 谢谢。我最喜欢地图方法。如果您添加答案,我会选择它作为最佳答案。
      • 添加了我的解决方案作为答案。
      • 我发现我的方式很有用,当我需要覆盖范围或在不完全相等的条件下进行选择时。
      猜你喜欢
      • 1970-01-01
      • 2020-09-16
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 2011-08-07
      • 1970-01-01
      • 2015-04-08
      • 1970-01-01
      相关资源
      最近更新 更多