ZetCode

Dart Switch 表达式

最后修改日期:2025 年 6 月 4 日

在 Dart 中,**switch 表达式** 提供了一种简洁而强大的**模式匹配**方法。它们在 Dart 3.0 中引入,提高了可读性,并提供了一种比传统 switch 语句更具表达力的替代方案。

与传统的 switch 语句不同,switch 表达式会计算出一个值,从而实现更灵活的控制流。它们支持**穷举检查**,确保所有可能的情况都得到处理,并集成了高级模式匹配,以最少的代码实现复杂的条件逻辑。

基本 Switch 表达式

switch 表达式最简单的形式匹配常量值。它根据匹配到的情况返回一个值。

main.dart
void main() {
  var day = 'Monday';
  
  var message = switch (day) {
    'Monday' => 'Start of work week',
    'Friday' => 'Almost weekend',
    'Saturday' || 'Sunday' => 'Weekend!',
    _ => 'Midweek day',
  };
  
  print(message);
}

此示例显示了一个匹配字符串值的基本 switch 表达式。下划线 (_) 是默认情况。该表达式返回一个赋给 message 的字符串。

$ dart main.dart
Start of work week

匹配 Enum 值

Switch 表达式与枚举(enums)特别契合。Dart 在切换枚举时可确保穷举检查。

main.dart
enum Status { pending, approved, rejected }

void main() {
  var currentStatus = Status.approved;
  
  var response = switch (currentStatus) {
    Status.pending => 'Please wait',
    Status.approved => 'Request approved',
    Status.rejected => 'Request denied',
  };
  
  print(response);
}

Switch 表达式涵盖了所有可能的枚举值。如果缺少任何枚举值,Dart 会发出警告。这可以防止由于未处理的情况而导致的运行时错误。

$ dart main.dart
Request approved

使用 Record 进行模式匹配

Switch 表达式可以解构并匹配 Dart 的 record。这使得以简洁的语法实现复杂的模式匹配成为可能。

main.dart
void main() {
  var point = (2, 3);
  
  var quadrant = switch (point) {
    (0, 0) => 'Origin',
    (var x, var y) when x > 0 && y > 0 => 'Quadrant I',
    (var x, var y) when x < 0 && y > 0 => 'Quadrant II',
    (var x, var y) when x < 0 && y < 0 => 'Quadrant III',
    (var x, var y) when x > 0 && y < 0 => 'Quadrant IV',
    (_, _) => 'On axis',
  };
  
  print(quadrant);
}

此示例匹配代表点的 record。它使用 `when` 保护子句进行条件匹配。变量 `x` 和 `y` 从 record 中提取。

$ dart main.dart
Quadrant I

匹配对象类型

Switch 表达式可以匹配和转换对象类型。这对于以类型安全的方式处理不同类型很有用。

main.dart
abstract class Shape {}
class Circle implements Shape {
  final double radius;
  Circle(this.radius);
}
class Square implements Shape {
  final double side;
  Square(this.side);
}

void main() {
  Shape shape = Circle(5.0);
  
  var area = switch (shape) {
    Circle(radius: var r) => 3.14 * r * r,
    Square(side: var s) => s * s,
    _ => 0.0,
  };
  
  print('Area: $area');
}

Switch 表达式匹配 `Shape` 的具体类型。它使用对象模式提取属性。这提供了类型安全的属性访问,无需显式转换。

$ dart main.dart
Area: 78.5

高级模式匹配

Switch 表达式支持包括嵌套模式和逻辑运算符在内的复杂模式。这使得复杂的匹配场景成为可能。

main.dart
void main() {
  var data = [
    ['admin', '12345'],
    ['user', 'password'],
    ['guest', null]
  ];
  
  for (var creds in data) {
    var access = switch (creds) {
      ['admin', _] => 'Full access',
      ['user', var pwd?] when pwd.length >= 8 => 'User access',
      ['user', _] => 'Weak password',
      [_, null] => 'No password',
      _ => 'Unknown user',
    };
    
    print('${creds[0]}: $access');
  }
}

此示例显示了带有条件逻辑的嵌套列表模式。模式匹配列表的结构和内容。保护子句提供了额外的条件。

$ dart main.dart
admin: Full access
user: Weak password
guest: No password

最佳实践

来源

Dart Switch 表达式文档

本教程通过实际示例介绍了 Dart 的 switch 表达式,演示了它们的模式匹配功能和简洁的语法。

作者

我叫 Jan Bodnar,是一名充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 Dart 教程