Menu
CoddyTech

记录(Dart 3)

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

Dart 3 引入了记录,这是一种轻量级的方式,可以将多个值组合在一起,而无需创建完整的类。记录不可变,具有内置的相等性,非常适合从函数返回多个值或临时组合相关数据。

将值放在括号中,即可创建记录:

void main() {
  // 包含两个值的简单记录
  var point = (10, 20);
  print(point.$1);  // 10:访问第一个元素
  print(point.$2);  // 20:访问第二个元素
  
  // 带命名字段的记录
  var person = (name: 'Alice', age: 30);
  print(person.name);  // Alice
  print(person.age);   // 30
}

位置字段通过 $1、$2 等访问,而命名字段直接使用字段名。你可以在同一条记录中混用这两种方式。

从函数返回多个值时,记录非常有用,不必为了返回两项数据而专门创建一个类:

(int, int) divideWithRemainder(int a, int b) {
  return (a ~/ b, a % b);
}

(String name, int age) getUser() {
  return ('Bob', 25);
}

void main() {
  var (quotient, remainder) = divideWithRemainder(17, 5);
  print('$quotient remainder $remainder');  // 3 remainder 2
  
  var (name, age) = getUser();
  print('$name is $age');  // Bob is 25
}

记录会根据其值自动支持相等比较,因此你无需自己实现 ==,比较起来很方便。需要简单、不可变的数据分组时使用记录;需要方法、可变性或更复杂的行为时使用类。

challenge icon

挑战

简单

让我们用记录构建一个坐标系!你将创建一些函数,用记录表示的二维点进行操作,借此了解记录如何让你轻松返回和处理多个相关值,而无需创建完整的类。

你将把代码整理到两个文件中:

  • geometry.dart:创建使用记录处理坐标数据的函数:
    • 创建函数 createPoint(int x, int y),返回一个包含命名字段 x 和 y 的记录。返回类型应为 ({int x, int y})
    • 创建函数 midpoint(({int x, int y}) p1, ({int x, int y}) p2),计算并返回两个点的中点,返回值为包含命名字段的记录。计算时使用整数除法(~/)
    • 创建函数 distance(({int x, int y}) p1, ({int x, int y}) p2),返回一个包含位置字段的记录:水平距离(x 的差值)和垂直距离(y 的差值)。返回类型应为 (int, int)。计算方式为 p2.x - p1.x 和 p2.y - p1.y
  • main.dart:导入几何文件,并演示记录的实际用法:
    • 使用 createPoint 创建两个点:点 A 的坐标为 (2, 4),点 B 的坐标为 (10, 8)
    • 使用命名字段打印 Point A: ([x], [y])
    • 使用命名字段打印 Point B: ([x], [y])
    • 计算中点并打印 Midpoint: ([x], [y])
    • 计算距离,并使用解构将值提取到变量 dx 和 dy 中,然后打印 Distance: dx=[dx], dy=[dy]

注意,记录可以让你简洁地返回多个值:当含义很重要时,使用命名字段会更清楚;当上下文足够明确时,则可以使用位置字段!

预期输出:

Point A: (2, 4)
Point B: (10, 8)
Midpoint: (6, 6)
Distance: dx=8, dy=4

亲手试试

import 'geometry.dart';

void main() {
  // TODO: 使用 createPoint 在 (2, 4) 创建点 A
  
  // TODO: 使用 createPoint 在 (10, 8) 创建点 B
  
  // TODO: 使用命名字段打印点 A:Point A: ([x], [y])
  
  // TODO: 使用命名字段打印点 B:Point B: ([x], [y])
  
  // TODO: 计算中点并打印:Midpoint: ([x], [y])
  
  // TODO: 计算距离,并使用解构将结果提取到 dx 和 dy
  // 然后打印:Distance: dx=[dx], dy=[dy]
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Dart 在线编译器