Menu
CoddyTech

模式与匹配(3.0)

本课属于 Coddy Dart 学习旅程的“面向对象编程”单元。第 87 课,共 110 课。

Dart 3 引入了模式匹配,这是一种强大的方式,可以在一个表达式中解构和检查数据。模式可以让你一次性从对象中提取值、检查对象的结构并绑定变量。

你已经了解了记录的基本解构。模式将这种用法扩展到对象、列表和映射:

void main() {
  // 列表模式
  var numbers = [1, 2, 3];
  var [a, b, c] = numbers;
  print('$a, $b, $c');  // 1, 2, 3
  
  // 映射模式
  var user = {'name': 'Alice', 'age': 30};
  var {'name': name, 'age': age} = user;
  print('$name is $age');  // Alice is 30
}

模式在 switch 表达式中尤其强大。你可以同时按类型、值和结构进行匹配:

String describe(Object obj) {
  return switch (obj) {
    int n when n < 0 => 'Negative number',
    int n => 'Positive number: $n',
    String s => 'String of length ${s.length}',
    [int first, ...] => 'List starting with $first',
    _ => 'Something else',
  };
}

void main() {
  print(describe(-5));        // 负数
  print(describe(42));        // 正数:42
  print(describe([1, 2, 3])); // 以 1 开头的列表
}

when 子句为模式添加条件,... 用于匹配列表中的剩余元素。下划线 _ 充当通配符,可以匹配任何内容。结合密封类,模式可以实现对复杂数据结构全面且类型安全的处理。

challenge icon

挑战

简单

让我们构建一个使用模式匹配来分析并分类不同输入类型的数据分类器!你将创建一个系统,使用 Dart 3 强大的模式匹配功能来识别并描述各种数据结构。

你将把代码分成两个文件:

  • classifier.dart:创建一个名为 classify 的函数,它接收一个 Object 参数,并返回一个 String 描述。使用带模式匹配的 switch 表达式处理以下情况:
    • 空列表 [] 应返回 Empty list
    • 恰好包含一个整数元素的列表应返回 Single item: [value]
    • 恰好包含两个元素的列表应返回 Pair: [first] and [second]
    • 以整数开头且后面还有其他元素的列表应返回 List starting with [first], length: [total length](使用 ... 剩余模式)
    • 同时包含 'name' 和 'age' 键的映射应返回 [name] is [age] years old(使用映射模式解构)
    • 负整数(使用 when 子句)应返回 Negative: [value]
    • 值为零的整数应返回 Zero
    • 其他任意整数应返回 Positive: [value]
    • 其他任意值应返回 Unknown type
  • main.dart:导入你的分类器,并用各种输入演示模式匹配。打印对以下每个值进行分类后的结果:
    • 空列表 []
    • 包含一个元素的列表:[42]
    • 包含两个元素的列表:['hello', 'world']
    • 更长的列表:[1, 2, 3, 4, 5]
    • 映射:{'name': 'Alice', 'age': 25}
    • 整数 -10
    • 整数 0
    • 整数 99

这个挑战结合了列表模式、映射模式、用于守卫条件的 when 子句,以及剩余模式(...)。这些都是本课介绍的关键模式匹配功能!

预期输出:

Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99

亲手试试

import 'classifier.dart';

void main() {
  // TODO: 使用 classify 函数对每个值进行分类
  // 并打印结果
  
  // 用空列表进行测试
  print(classify([]));
  
  // TODO: 用只包含一个元素的列表进行测试:[42]
  
  // TODO: 用包含两个元素的列表进行测试:['hello', 'world']
  
  // TODO: 用更长的列表进行测试:[1, 2, 3, 4, 5]
  
  // TODO: 用映射进行测试:{'name': 'Alice', 'age': 25}
  
  // TODO: 用整数 -10 进行测试
  
  // TODO: 用整数 0 进行测试
  
  // TODO: 用整数 99 进行测试
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Dart 在线编译器