Dart 的枚举类型的高阶用法
[》跳过拾光记忆]
拾光记忆
简介: 针对 Flutter 项目资产管理的脚本服务。Fam 具有以下特点: 支持多种平台以及各平台无差异化、界面美观、功能齐全、快捷方便。 推荐: ⭐️⭐️⭐️⭐️⭐️
简介: 针对 Flutter 多手指检测以及手势触发其他手势也触发的问题。 推荐: ⭐️⭐️⭐️⭐️⭐️
[返回拾光记忆《]
一、枚举简介
枚举类型\color{#FF0000}{枚举类型}枚举类型 在 C++ 或者 VB 等一些计算机编程语言中是一种基本的数据类型而不是构造数据类型。而在 C 语言计算机编程语言中是一种 构造数据类型,而我们的 Dart 中的枚举属于这种。它用于声明一组命名的常数,当一个变量可能有几种取值时,可以将它定义为枚举类型。
数据类型\color{#FF00FF}{数据类型}数据类型 : 数据元( Data Element),也称为数据元素,是用一组属性描述其定义、标识、表示和允许值的数据单元,在一定语境下,通常用于构建一个语义正确、独立且无歧义的特定概念语义的信息单元。数据元可以理解为数据的基本单元,将若干具有相关性的数据元按一定的次序组成一个整体结构即为数据模型。
二、Dart 的枚举
1. Dart 中使用 enum 关键字定义枚举类型,语法形式如下:
enum class_name {
member1,
member2,
member3,
......
}
语法分析:
- enum 是枚举引入的关键字。
- class_name 是引入的枚举类名。
- 枚举类中的数据成员之间必须使用逗号分隔。
- 枚举中的成员都有一个与自己对应的索引值,索引值是从 0 开始的。
注意:\color{#FF00FF}{注意:}注意: 可能你看到有的博客或者讲师以及开发者说枚举最后一个成员不可以使用逗号,这是 不对的 。Dart 中的枚举最后一个成员 可以使用逗号或者不使用。官方的枚举最后一个成员后面都有逗号。
2. Dart 最简单的枚举
enum Festival {
chunjie,
yuanxiaojie,
qingmingjie,
duanwujie,
zhongqiujie,
chongyangjie,
}
枚举的基本使用如下:
-
获取枚举所有的成员, 使用
枚举类名.values
, 如下所示:void main() { for (var element in Festival.values) { print(element); } }
上面输出:
flutter: Festival.chunjie flutter: Festival.yuanxiaojie flutter: Festival.qingmingjie flutter: Festival.duanwujie flutter: Festival.zhongqiujie flutter: Festival.chongyangjie
-
获取成员的索引值,使用
成员.index
, 如下所示:print(Festival.chunjie.index);
上面输出:
flutter: 0
-
获取成员的名字,使用
成员.name
, 如下所示:print(Festival.chunjie.name);
上面输出:
flutter: chunjie
注意:\color{#FF00FF}{注意:}注意:
Festival.chunjie.name
和Festival.chunjie.toString()
的区别是前者输出是chunjie
后者的输出是Festival.chunjie
。
3. 枚举的扩展 ⭐️
枚举的扩展只能扩展方法不能扩展枚举成员\color{#FF0F0F}{只能扩展方法不能扩展枚举成员}只能扩展方法不能扩展枚举成员。例如: 给定索引值,获取对应的枚举类型。扩展如下:
enum Festival {
chunjie,
yuanxiaojie,
qingmingjie,
duanwujie,
zhongqiujie,
chongyangjie,
}
// 扩展
extension FestivalType on Festival {
static Festival getTypeFormIndex(int index) {
return Festival.values[index];
}
}
扩展后的使用:
void main() {
final Festival type = FestivalType.getTypeFormIndex(2);
print(type);
}
上面输出为:
flutter: Festival.qingmingjie
这常用于后台把一个属性不同类型定义为数字,然而项目里面是定义的枚举类型。在网络请求的数据处理时就需要一个映射对应。而对枚举扩展是最好的方法。
4.枚举可包含多种数据类型 ⭐️ ⭐️
正常的枚举不能包含其他数据类型,但是业务的扩展使得这样简单的枚举对开发带来不小的处理负担。有没有方法可以让枚举包含其他的数据类型?答案是:有的!\color{#FF0F0F}{有没有方法可以让枚举包含其他的数据类型?答案是:有的!}有没有方法可以让枚举包含其他的数据类型?答案是:有的!。这就是下面要介绍的枚举以类型的形式定义。代码如下:
enum WorkType {
electrician(name: '电工', grade: 2),
bricklayer(name: '瓦工', grade: 3),
carpentry(name: '木工', grade: 1);
const WorkType({required this.name, required this.grade});
final String name;
final int grade;
}
📢注意:\color{#ff0f0f}{📢 注意:}📢注意:
- 定义的属性是不可变的,需要使用
final
关键字修饰。 - 构造方法前的
const
关键字不可缺少。 - 各个枚举成员之间使用
逗号 ,
分隔,最后一个成员使用分号 ;
结尾。
该枚举的使用:
void main() {
final String name = WorkType.bricklayer.name;
print(name);
final int grade = WorkType.carpentry.grade;
print(grade);
}
上面输出为:
flutter: 瓦工
flutter: 1
三、Dart 的枚举扩展介绍
1. 为什么所有的枚举成员都有个数字标识符?
答: 这是因为使用 enum
关键字引入了 Enum
类。定义的枚举实现了 Enum
类的index
属性。代码如下:
@Since("2.14")
abstract class Enum {
int get index;
String get _name;
......
}
2. 为什么所有枚举成员可以获取名字?
答: 因为类 Enum
进行扩展了 name
方法。代码如下:
@Since("2.15")
extension EnumName on Enum {
String get name => _name;
}
3. Enum
类还提供了两个枚举的比较的方法
-
static int compareByIndex<T extends Enum>(T value1, T value2) => value1.index - value2.index;
通过枚举成员的索引值比较大小。代码如下:final int compare = Enum.compareByIndex(Festival.chunjie, Festival.yuanxiaojie); print(compare); final int compare1 = Enum.compareByIndex(Festival.chunjie, Festival.chunjie); print(compare1); final int compare2 = Enum.compareByIndex(Festival.yuanxiaojie, Festival.chunjie); print(compare2);
上面代码输出为:
flutter: -1 flutter: 0 flutter: 1
上述代码总结:
- 如果
Enum.compareByIndex
的结果小于零,则value1
的枚举成员排序靠前;value2
枚举成员排序靠后。 - 如果
Enum.compareByIndex
的结果等于零,则value1
和value2
枚举成员是同一个。 - 如果
Enum.compareByIndex
的结果大于零,则value1
的枚举成员排序靠后;value2
枚举成员排序靠前。
- 如果
-
static int compareByName<T extends Enum>(T value1, T value2) => value1.name.compareTo(value2.name);
比较枚举成员名字的大小。(个人觉得很鸡肋,没有多大实际用途\color{#00ff00}{个人觉得很鸡肋,没有多大实际用途}个人觉得很鸡肋,没有多大实际用途)
4. 对枚举类型的集合进行扩展
-
扩展代码
@Since("2.15") extension EnumByName<T extends Enum> on Iterable<T> { // 通过字符串获取枚举 T byName(String name) { for (var value in this) { if (value._name == name) return value; } throw ArgumentError.value(name, "name", "No enum value with that name"); } Map<String, T> asNameMap() => <String, T>{for (var value in this) value._name: value}; }
-
通过名字获取枚举类型。
void main() { final Festival festival = Festival.values.byName('chunjie'); print(festival); }
上面代码输出:
flutter: Festival.chunjie
-
将集合类型的枚举,按名字转化为字典集合
void main() { final Map<String, Festival> fMap = Festival.values.asNameMap(); print(fMap); }
上面代码输出:
flutter: { chunjie: Festival.chunjie, yuanxiaojie: Festival.yuanxiaojie, qingmingjie: Festival.qingmingjie, duanwujie: Festival.duanwujie, zhongqiujie: Festival.zhongqiujie, chongyangjie: Festival.chongyangjie }
转载自:https://juejin.cn/post/7193614523486437433