记录(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
}记录会根据其值自动支持相等比较,因此你无需自己实现 ==,比较起来很方便。需要简单、不可变的数据分组时使用记录;需要方法、可变性或更复杂的行为时使用类。
挑战
简单让我们用记录构建一个坐标系!你将创建一些函数,用记录表示的二维点进行操作,借此了解记录如何让你轻松返回和处理多个相关值,而无需创建完整的类。
你将把代码整理到两个文件中:
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]
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Dart 在线编译器