分支
本页介绍如何使用分支控制 Dart 代码的流程
if
语句和元素if-case
语句和元素switch
语句和表达式
你还可以使用以下方式在 Dart 中操作控制流
If
#Dart 支持带有可选 else
子句的 if
语句。if
后括号中的条件必须是求值为布尔值的表达式。
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
要了解如何在表达式上下文中使用 if
,请查看条件表达式。
If-case
#Dart if
语句支持后跟模式的 case
子句。
if (pair case [int x, int y]) return Point(x, y);
如果模式与值匹配,则分支将执行,并且模式定义的任何变量都在作用域内。
在前面的示例中,列表模式 [int x, int y]
匹配值 pair
,因此分支 return Point(x, y)
使用模式定义的变量 x
和 y
执行。
否则,控制流将进行到 else
分支(如果存在)以执行。
if (pair case [int x, int y]) {
print('Was coordinate array $x,$y');
} else {
throw FormatException('Invalid coordinates.');
}
if-case
语句提供了一种针对单个模式匹配和解构的方法。要针对多个模式测试值,请使用 switch。
Switch 语句
#switch
语句针对一系列 case
评估值表达式。每个 case
子句都是一个模式,用于与值进行匹配。你可以使用任何类型的模式作为 case
。
当值与 case
的模式匹配时,case
主体将执行。非空的 case
子句在完成后跳转到 switch
的末尾。它们不需要 break
语句。结束非空 case
子句的其他有效方法是 continue
、throw
或 return
语句。
当没有 case
子句匹配时,使用 default
或通配符 _
子句来执行代码。
var command = 'OPEN';
switch (command) {
case 'CLOSED':
executeClosed();
case 'PENDING':
executePending();
case 'APPROVED':
executeApproved();
case 'DENIED':
executeDenied();
case 'OPEN':
executeOpen();
default:
executeUnknown();
}
空 case
会落入下一个 case
,允许 case
共享一个主体。对于不落入的空 case
,请使用 break
作为其主体。对于非顺序落入,你可以使用 continue
语句和标签。
switch (command) {
case 'OPEN':
executeOpen();
continue newCase; // Continues executing at the newCase label.
case 'DENIED': // Empty case falls through.
case 'CLOSED':
executeClosed(); // Runs for both DENIED and CLOSED,
newCase:
case 'PENDING':
executeNowClosed(); // Runs for both OPEN and PENDING.
}
你可以使用逻辑或模式来允许 case
共享主体或守卫。要了解有关模式和 case
子句的更多信息,请查看关于 Switch 语句和表达式的模式文档。
Switch 表达式
#switch
表达式根据匹配的 case
的表达式主体生成一个值。你可以在 Dart 允许表达式的任何地方使用 switch
表达式,但表达式语句的开头除外。例如:
var x = switch (y) { ... };
print(switch (x) { ... });
return switch (x) { ... };
如果想在表达式语句的开头使用 switch
,请使用 switch 语句。
switch
表达式允许你像这样重写 switch
语句:
// Where slash, star, comma, semicolon, etc., are constant variables...
switch (charCode) {
case slash || star || plus || minus: // Logical-or pattern
token = operator(charCode);
case comma || semicolon: // Logical-or pattern
token = punctuation(charCode);
case >= digit0 && <= digit9: // Relational and logical-and patterns
token = number();
default:
throw FormatException('Invalid');
}
像这样变成一个表达式:
token = switch (charCode) {
slash || star || plus || minus => operator(charCode),
comma || semicolon => punctuation(charCode),
>= digit0 && <= digit9 => number(),
_ => throw FormatException('Invalid'),
};
switch
表达式的语法与 switch
语句语法不同:
case
不以case
关键字开头。case
主体是一个表达式,而不是一系列语句。- 每个
case
都必须有一个主体;空case
没有隐式落入。 case
模式使用=>
而不是:
与其主体分隔。case
用,
分隔(并允许可选的尾随,
)。- 默认
case
只能使用_
,而不是同时允许default
和_
。
穷尽性检查
#穷尽性检查是一项功能,如果值可能进入 switch
但与任何 case
都不匹配,则会报告编译时错误。
// Non-exhaustive switch on bool?, missing case to match null possibility:
switch (nullableBool) {
case true:
print('yes');
case false:
print('no');
}
默认 case
(default
或 _
) 涵盖了可以流经 switch
的所有可能值。这使得任何类型的 switch
都是穷尽的。
枚举和密封类型对于 switch
特别有用,因为即使没有默认 case
,它们的可能值也是已知的且完全可枚举的。在类上使用 sealed
修饰符,以便在切换该类的子类型时启用穷尽性检查。
sealed class Shape {}
class Square implements Shape {
final double length;
Square(this.length);
}
class Circle implements Shape {
final double radius;
Circle(this.radius);
}
double calculateArea(Shape shape) => switch (shape) {
Square(length: var l) => l * l,
Circle(radius: var r) => math.pi * r * r,
};
如果有人要添加 Shape
的新子类,则此 switch
表达式将不完整。穷尽性检查会通知你缺少的子类型。这允许你以某种函数式代数数据类型风格使用 Dart。
守卫子句
#要在 case
子句后设置可选的守卫子句,请使用关键字 when
。守卫子句可以跟随 if case
,以及 switch
语句和表达式。
// Switch statement:
switch (something) {
case somePattern when some || boolean || expression:
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clause.
body;
}
// Switch expression:
var value = switch (something) {
somePattern when some || boolean || expression => body,
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clause.
}
// If-case statement:
if (something case somePattern when some || boolean || expression) {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Guard clause.
body;
}
守卫在匹配后评估任意布尔表达式。这允许你添加更多关于 case
主体是否应该执行的约束。当守卫子句求值为 false 时,执行会进行到下一个 case
,而不是退出整个 switch
。
除非另有说明,否则本网站上的文档反映了 Dart 3.7.1。页面上次更新于 2025-02-12。 查看源代码 或 报告问题。