Dart 密封类
最后修改日期:2025 年 6 月 5 日
本教程探讨 Dart 密封类,演示它们在创建用于状态管理和模式匹配的类型安全、详尽的层级结构中的用法。
Dart 中的密封类是一个使用 sealed 关键字标记的特殊抽象类。它限制其子类只能在同一个库中定义,从而使编译器能够了解所有可能的子类。这允许在 switch 表达式中使用详尽的模式匹配,确保所有情况都得到处理,从而提高类型安全性并减少运行时错误。
Dart 密封类概述
密封类非常适合模拟有限状态层级,例如 UI 状态、网络响应或代数数据类型。它们利用 Dart 的模式匹配来简洁地处理每个子类,通常使用解构属性以直接访问的 switch 表达式。
| 功能 | 描述 | 示例 |
|---|---|---|
| 密封 | 限制子类在同一个库中 | sealed class Shape {} |
| 子类 | 固定的实现集 | class Circle extends Shape {} |
| 模式匹配 | 详尽的 switch 处理 | switch (shape) { case Circle(): ... } |
用于形状的基本密封类
此示例定义了一个用于几何形状的密封类层级,并使用模式匹配来计算它们的面积。
sealed class Shape {}
class Circle extends Shape {
final double radius;
Circle(this.radius);
}
class Square extends Shape {
final double side;
Square(this.side);
}
class Triangle extends Shape {
final double base;
final double height;
Triangle(this.base, this.height);
}
double calculateArea(Shape shape) {
switch (shape) {
case Circle(:final radius):
return 3.14 * radius * radius;
case Square(:final side):
return side * side;
case Triangle(:final base, :final height):
return 0.5 * base * height;
}
}
void main() {
var circle = Circle(5);
var square = Square(4);
var triangle = Triangle(3, 6);
print('Circle area: ${calculateArea(circle)}');
print('Square area: ${calculateArea(square)}');
print('Triangle area: ${calculateArea(triangle)}');
}
Shape 密封类有三个子类:Circle、Square 和 Triangle。calculateArea 函数使用 switch 表达式来计算面积,解构 radius 等属性以进行简洁访问。编译器确保覆盖所有情况,防止未处理的状态。
$ dart run shapes.dart Circle area: 78.5 Square area: 16.0 Triangle area: 9.0
网络请求状态
密封类可用于模拟网络请求状态,例如加载、成功或错误条件,并提供类型安全的处理。
sealed class HttpState {}
class Loading extends HttpState {}
class Error extends HttpState {
final String message;
Error(this.message);
}
class Loaded extends HttpState {
final String data;
Loaded(this.data);
}
void handleState(HttpState state) {
switch (state) {
case Loading():
print('⏳ Loading...');
case Loaded(:final data):
print('✅ Success! Response: $data');
case Error(:final message):
print('❌ Error: $message');
}
}
void main() {
handleState(Loading());
handleState(Loaded('Data loaded successfully!'));
handleState(Error('Failed to load data.'));
}
HttpState 密封类表示网络状态。Loading 表示正在进行的请求,Loaded 包含响应数据,Error 存储错误消息。handleState 函数使用模式匹配来处理每种状态,确保所有可能性都得到详尽处理。
$ dart run http_state.dart ⏳ Loading... ✅ Success! Response: Data loaded successfully! ❌ Error: Failed to load data.
带工厂构造函数的密封类
密封类可以使用工厂构造函数来创建子类的实例,为结果处理提供干净的 API。
sealed class Result<T> {
const Result();
factory Result.success(T value) = Success<T>;
factory Result.failure(String error) = Failure<T>;
}
class Success<T> implements Result<T> {
final T value;
Success(this.value);
}
class Failure<T> implements Result<T> {
final String error;
Failure(this.error);
}
void processResult(Result<int> result) {
switch (result) {
case Success(:final value):
print('Success with value: $value');
case Failure(:final error):
print('Failure with error: $error');
}
}
void main() {
Result<int> successResult = Result.success(42);
Result<int> failureResult = Result.failure('An error occurred');
processResult(successResult);
processResult(failureResult);
}
Result<T> 密封类使用泛型来模拟成功或失败的结果。工厂构造函数 Result.success 和 Result.failure 创建 Success 或 Failure 实例。processResult 函数使用模式匹配来处理结果,直接访问 value 或 error。
$ dart run result.dart Success with value: 42 Failure with error: An error occurred
用户认证状态
密封类可以模拟用户认证状态,例如未认证、已认证或访客访问,并提供类型安全的处理。
sealed class AuthState {}
class Unauthenticated extends AuthState {}
class Authenticated extends AuthState {
final String userId;
Authenticated(this.userId);
}
class Guest extends AuthState {
final String sessionId;
Guest(this.sessionId);
}
void handleAuth(AuthState state) {
switch (state) {
case Unauthenticated():
print('🔓 Please log in to continue.');
case Authenticated(:final userId):
print('👤 Logged in as user: $userId');
case Guest(:final sessionId):
print('🌐 Guest access with session: $sessionId');
}
}
void main() {
handleAuth(Unauthenticated());
handleAuth(Authenticated('user123'));
handleAuth(Guest('session456'));
}
AuthState 密封类定义了认证状态。Unauthenticated 表示未登录,Authenticated 包含用户 ID,Guest 包含会话 ID。handleAuth 函数使用模式匹配来处理每种状态,确保所有情况都得到覆盖。
$ dart run auth_state.dart 🔓 Please log in to continue. 👤 Logged in as user: user123 🌐 Guest access with session: session456
数学表达式
密封类可以表示数学表达式,通过模式匹配实现递归求值,用于复杂计算。
sealed class Expression {}
class Number extends Expression {
final double value;
Number(this.value);
}
class Add extends Expression {
final Expression left;
final Expression right;
Add(this.left, this.right);
}
class Multiply extends Expression {
final Expression left;
final Expression right;
Multiply(this.left, this.right);
}
double evaluate(Expression expr) {
switch (expr) {
case Number(:final value):
return value;
case Add(:final left, :final right):
return evaluate(left) + evaluate(right);
case Multiply(:final left, :final right):
return evaluate(left) * evaluate(right);
}
}
void main() {
var expr = Add(
Number(2),
Multiply(Number(3), Number(4)),
);
print('Result: ${evaluate(expr)}');
}
Expression 密封类使用 Number、Add 和 Multiply 子类来模拟数学表达式树。evaluate 函数使用模式匹配递归计算结果,处理表达式 2 + (3 * 4) 得到 14。
$ dart run expression.dart Result: 14.0
来源
本教程演示了 Dart 密封类,展示了它们在创建用于状态管理和模式匹配的类型安全、详尽的层级结构方面的强大功能。
作者
列出 所有 Dart 教程。