Dart 中的枚举类型
最后修改于 2025 年 5 月 25 日
Dart 中的枚举(enumeration)是一种特殊的类,用于表示固定数量的常量值。本教程将涵盖 Dart 的枚举类型,从基本用法到增强枚举和模式匹配等高级功能。
Dart 枚举概述
Dart 的枚举类型允许您定义一组命名常量值。枚举适用于表示一组固定的相关选项,例如一周中的某几天、交通灯的状态或用户角色。Dart 的枚举系统简单而强大,提供了内置的属性和方法,使得处理枚举变得简单高效。
Dart 中的枚举可以是基本的,仅表示一组命名常量;也可以是增强的,可以包含属性、方法和构造函数。Dart 还支持枚举的模式匹配,从而实现简洁且富有表现力的 switch 语句和表达式。
| 功能 | 描述 | 示例 |
|---|---|---|
| 基本枚举 | 简单的命名常量集 | enum Color { red, green, blue } |
| 增强枚举 | 带有属性和方法的枚举 | enum Status { active('A'), inactive('I') } |
| Switch 匹配 | 枚举的模式匹配 | switch(color) { case Color.red: ... } |
| 枚举属性 | 内置的索引和名称访问 | color.index, color.name |
基本枚举声明
Dart 中最简单的枚举形式是声明一组命名常量值。这些枚举适用于表示一组固定的相关选项,其中每个选项同等重要且没有附加数据。
enum Day {
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday
}
void main() {
Day today = Day.friday;
print('Today is $today');
print('Day index: ${today.index}');
print('Day name: ${today.name}');
// Iterate all enum values
for (var day in Day.values) {
print('$day (${day.index})');
}
}
基本枚举会自动获得几个有用的属性。`index` 属性返回枚举值在其声明中的零基位置。`name` 属性返回枚举值的字符串表示。`values` 常量提供了一个按声明顺序排列的所有枚举值的列表。
$ dart run basic_enum.dart Today is Day.friday Day index: 4 Day name: friday Day.monday (0) Day.tuesday (1) Day.wednesday (2) Day.thursday (3) Day.friday (4) Day.saturday (5) Day.sunday (6)
增强枚举
Dart 的增强枚举允许向枚举声明添加属性、方法和构造函数。这项功能使枚举更强大,能够携带附加数据和行为。
enum Planet {
mercury(mass: 3.303e+23, radius: 2.4397e6),
venus(mass: 4.869e+24, radius: 6.0518e6),
earth(mass: 5.976e+24, radius: 6.37814e6),
mars(mass: 6.421e+23, radius: 3.3972e6);
final double mass;
final double radius;
double get gravity => 6.67430e-11 * mass / (radius * radius);
const Planet({required this.mass, required this.radius});
String describe() {
return '$name has mass ${mass.toStringAsExponential(1)} kg '
'and radius ${radius.toStringAsExponential(1)} m';
}
}
void main() {
Planet home = Planet.earth;
print(home.describe());
print('Surface gravity: ${home.gravity.toStringAsFixed(2)} m/s²');
// Compare enum values
if (home == Planet.earth) {
print('We are on Earth!');
}
}
增强枚举可以声明由常量构造函数初始化的 final 字段。它们还可以包含 getter 和方法以提供附加功能。每个枚举值都必须使用必需的参数调用构造函数。增强枚举语法在增加显著的表达能力的同时,保持了类型安全。
$ dart run enhanced_enum.dart earth has mass 6.0e+24 kg and radius 6.4e+6 m Surface gravity: 9.80 m/s² We are on Earth!
枚举的模式匹配
Dart 的 switch 表达式和模式匹配与枚举类型特别地配合得很好。这允许对所有可能的枚举值进行详尽检查,并提供编译时安全性。
enum TrafficLight {
red,
yellow,
green
}
String getTrafficInstruction(TrafficLight light) {
return switch (light) {
TrafficLight.red => 'Stop',
TrafficLight.yellow => 'Caution',
TrafficLight.green => 'Go',
};
}
void main() {
TrafficLight current = TrafficLight.yellow;
print(getTrafficInstruction(current));
// Exhaustive checking
for (var light in TrafficLight.values) {
print('$light: ${getTrafficInstruction(light)}');
}
}
当使用枚举的 switch 表达式时,Dart 可以确保所有情况都得到处理。如果稍后添加了新的枚举值,编译器会标记任何未处理该值的情况的 switch 语句。这种详尽的检查有助于防止未处理情况导致的运行时错误。模式匹配语法简洁,并清晰地表达了枚举值与其对应行为之间的映射关系。
$ dart run pattern_matching.dart Caution TrafficLight.red: Stop TrafficLight.yellow: Caution TrafficLight.green: Go
枚举属性和方法
所有 Dart 枚举都自动附带几个有用的属性和方法。这些内置成员使得在没有额外样板代码的情况下轻松使用枚举值。
enum Direction {
north,
south,
east,
west
}
void main() {
Direction heading = Direction.east;
// Built-in properties
print('Index: ${heading.index}');
print('Name: ${heading.name}');
// Access all values
print('All directions:');
for (var dir in Direction.values) {
print('${dir.name.toUpperCase()} (${dir.index})');
}
// Convert from string
String input = 'south';
Direction? parsed = Direction.values.asNameMap()[input];
print('Parsed direction: $parsed');
}
`index` 属性返回枚举值在其声明中的零基位置。`name` 属性提供枚举值的字符串表示。静态 `values` 常量包含按声明顺序排列的所有枚举值。`asNameMap()` 方法创建了一个从名称到枚举值的查找表,这对于将字符串解析为枚举值非常有用。
$ dart run enum_properties.dart Index: 2 Name: east All directions: NORTH (0) SOUTH (1) EAST (2) WEST (3) Parsed direction: Direction.south
将枚举与其他特性混合使用
Dart 枚举与其他语言特性(如泛型、扩展和工厂构造函数)配合良好。这允许强大的组合,可以优雅地解决复杂问题。
enum ApiStatus {
success,
failure,
loading;
factory ApiStatus.fromCode(int code) {
return switch (code) {
200 => ApiStatus.success,
400 || 500 => ApiStatus.failure,
_ => ApiStatus.loading,
};
}
}
extension ApiStatusExtension on ApiStatus {
String get message => switch (this) {
ApiStatus.success => 'Operation succeeded',
ApiStatus.failure => 'Operation failed',
ApiStatus.loading => 'Operation in progress',
};
}
void main() {
ApiStatus status = ApiStatus.fromCode(200);
print('Status: ${status.name}');
print('Message: ${status.message}');
status = ApiStatus.fromCode(500);
print('Status: ${status.name}');
print('Message: ${status.message}');
}
枚举中的工厂构造函数支持替代的创建模式,例如从其他数据类型解析。扩展可以在不修改其原始声明的情况下为枚举添加功能。这些特性与模式匹配的结合,产生了干净、可维护的代码,清晰地表达了程序的意图,同时保持了类型安全。
$ dart run mixed_features.dart Status: success Message: Operation succeeded Status: failure Message: Operation failed
来源
Dart 的枚举类型提供了一种健壮的方法来建模固定集合的相关值。从简单的常量集到具有属性和方法的增强枚举,它们提供不同级别的复杂性以满足您的需求。结合 Dart 的模式匹配功能,枚举在编写清晰、可维护的代码方面变得更加强大。
作者
列出 所有 Dart 教程。