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 教程。