模式应用案例

本文以示例的方式,介绍模式的几个经典应用案例。

交换两个变量的值

//ch0304_1.dart
void main() {
  var (x, y) = (3, 4);
  (x, y) = (y, x);
  assert(x == 4 && y == 3);
}

解构Map里的 key-value

//ch0304_2.dart
void main() {
  const employee = {"id": 1, "name": "Tom", "post": "CEO", "salary": 2};
  for (var MapEntry(:key, :value) in employee.entries) {
    print("$key: $value");
  }
  // Output:
  // id: 1
  // name: Tom
  // post: CEO
  // salary: 2
}

解构多个返回值

// ch0304_3.dart
void main() {
  var (ok, result) = foo();
  print(ok ? result : 'oops!');
}

(bool ok, String) foo() {
  // ...
  return (true, 'Everything is OK');
}

解构类实例

Object(对象)模式

代数(Algebraic)数据类型

当满足如下条件时,可使用代数数据类型这一风格去写代码:

  • 有一个相关类型的家族(family)。
  • 有一个操作,需要针对每种类型执行特定的行为。
  • 希望将这些行为集中到一起,而不是分散到不同的类型中。

这是一个来自官方文档的示例。

// ch0304_4.dart
import 'dart:math' as math;

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,
};

JSON/Map 校验

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,其应用极为广泛,尤其在互联网领域。JSON采用了独立于编程语言的文本格式。

// ch0304_5.dart
import 'dart:convert';

void main() {
  const dat = '''{
    "id": 1,
    "name": "Learning Dart from Zero",
    "category": "Digital Book",
    "tags": ["dart", "programming", "learning"],
    "website": "https://techo.dev/dartpl/"
  }'''; // 1

  final product = jsonDecode(dat); // 2
  print(product.runtimeType); // Output: _Map<String, dynamic>

  if (product case { // 3
    "id": int _,
    "name": String name,
    "tags": [String tag1, String tag2, _],
    "website": String website,
  }) {
    print("$name($website), tagged by $tag1 and $tag2");
  }
}
  1. dat 是一个JSON字符串;
  2. 使用 jsonDecode 函数解析 dat,其结果存于product变量,此处的product是一个Map;
  3. 使用模式校验product,并绑定相关的部件(parts)。

参考资料

https://dart.dev/language/patterns#use-cases-for-patterns