模式的使用场景

模式可用于下列地方:

局部变量声明和赋值

// ch0302_1.dart
void main() {
  var (name, :id, [a, b, c]) = ('Tom', id: 1, [3, 4, 5]); // 1
  print('name=$name id=$id a=$a b=$b c=$c');
  // Output: name=Tom id=1 a=3 b=4 c=5

  (a, b) = (b, a); // 2
  print('a=$a b=$b'); // Output: a=4 b=3
}
  1. 这行代码展示了模式如何用于局部变量声明;
  2. 这里使用了模式的局部变量赋值,交换两个变量的值。

if-case 和 switch-case

每个case子句都包含了一个模式,无论是if-case 还是switch-case。

// ch0302_2.dart
void main() {
  const data = ('Tom', id: 1, [3, 4, 5]);
  if (data case ('Tom' || 'Jerry', id: _, _)) { // 1
    print('Hey, my friend!');
  }

  switch (data) {
    case ('Tom', :var id, _):
      print('Hi, Tom! Your ID is $id.');
    case ('Jerry', :var id, _):
      print('Hi, Jerry! Your ID is $id.');
    default:
      print('Hi! Who are you?');
  }
}
  1. 这里使用了逻辑或(OR)操作符(||),让data.$1匹配多个值,这非常实用。

for 和 for-in 循环

// ch0302_3.dart
void main() {
  var points = [Point(0, 1), Point(1, 2), Point(2, 3)]; // 2
  for (var Point(:x, :y) in points) { // 3
    print('x=$x y=$y');
  }
}

class Point { // 1
  const Point(this.x, this.y);
  final double x;
  final double y;
}
  1. 定义Point类,它包括xy两个字段;
  2. points是一个Point列表;
  3. 在for-in语句中解构points中的每个Point,将其部件绑定至局部变量xy

集合字面量(collection literals)中的控制流

集合包括List、Set、Map,将在第6章将详细讨论,这里仅以List(列表)为例,对模式的相关使用进行说明。

首先来看如何使用for语句创建一个列表,以及forif的嵌套使用。下面的程序将打印数字0到9中的偶数。

// ch0302_4.dart
void main() {
  final nums = [for (var i = 0; i < 10; i++) i]; // 1
  var evenNums = [
    for (var num in nums) // 2
      if (num.isEven) num,
  ];
  print(evenNums); // Output: [0, 2, 4, 6, 8]
}
  1. 在集合字面量中使for语句,创建一个0到9的数字列表nums;
  2. nums进行过滤(if(num.isEven)),选出其中的偶数。

下例演示了如何在集合字面量的控制流中使用模式。

// ch0302_5.dart
void main() {
  var points = [for (var x = 0; x < 10; x++) (x: x, y: 2 * x)];
  var points2 = [
    for (var (:x, :y) in points)
      if (x.isEven) (x: x, y: y),
  ];
  print(points2);
}