枚举是在日常开发中经常使用的一种类型,Flutter 下的枚举,大概分为三个阶段:
1. Dart2.7之前版本
2. Dart2.7扩展函数版本
3. Flutter3.0的增强枚举类版本
以枚举 AnimalEnum 举例,解决两个常用场景:
枚举定义:
enum AnimalEnum {
dog,
cat,
chicken,
horse,
}
场景1 我们需要在业务层获取到枚举值映射的关联数据: 1.int值 2.枚举字符串 3.中文名称(label) 4.其他相关联的属性,(例如声音sound)
场景2 我们需要在业务层根据后端返回的枚举int值/枚举字符串来转换成枚举,以便进行一些逻辑判断,例如: 根据:字符串【"dog"】或者int值【101】 获取到枚举: AnimalEnum.dog;
1. Dart2.7之前版本
**场景1:**在Dart2.7的扩展函数发布之前,一般是新建一个顶级函数/工具类内部函数,使用swtich case来返回枚举值对应的关联数据:
///枚举转换int值
int getAnimalEnumInt(AnimalEnum animalEnum) {
switch (animalEnum) {
case AnimalEnum.dog:
return 101;
case AnimalEnum.cat:
return 102;
case AnimalEnum.chicken:
return 103;
case AnimalEnum.horse:
return 104;
}
}
///枚举转换字符串
String getAnimalEnumStr(AnimalEnum animalEnum) {
switch (animalEnum) {
case AnimalEnum.dog:
return 'dog';
case AnimalEnum.cat:
return 'cat';
case AnimalEnum.chicken:
return 'chicken';
case AnimalEnum.horse:
return 'horse';
}
}
///枚举转换label
String getAnimalEnumLabel(AnimalEnum animalEnum) {
switch (animalEnum) {
case AnimalEnum.dog:
return '小狗';
case AnimalEnum.cat:
return '小猫';
case AnimalEnum.chicken:
return '坤坤';
case AnimalEnum.horse:
return '小马';
}
}
///枚举转换声音
String getAnimalEnumSound(AnimalEnum animalEnum) {
switch (animalEnum) {
case AnimalEnum.dog:
return '汪汪';
case AnimalEnum.cat:
return '喵喵';
case AnimalEnum.chicken:
return '鸡你太美';
case AnimalEnum.horse:
return '吁~';
}
}
**场景2:**新建一个顶级函数/工具类内部函数,根据入参值来使用swtich case来返回对应的枚举值:
//根据枚举int值转换成枚举
AnimalEnum? getAnimalEnumFromInt(int enumInt) {
switch (enumInt) {
case 101:
return AnimalEnum.dog;
case 102:
return AnimalEnum.cat;
case 103:
return AnimalEnum.chicken;
case 104:
return AnimalEnum.horse;
default:
return null;
}
}
//根据枚举String值转换成枚举
AnimalEnum? getAnimalEnumFromStr(String enumStr) {
switch (enumStr) {
case 'dog':
return AnimalEnum.dog;
case 'cat':
return AnimalEnum.cat;
case 'chicken':
return AnimalEnum.chicken;
case 'horse':
return AnimalEnum.horse;
default:
return null;
}
}
2. Dart2.7扩展函数版本
随着dart2.7的发布,Dart新增了扩展函数,使枚举相关的代码定义、调用更加简洁
**场景1:**在dart的扩展函数发布之后,一般是对枚举新建扩展函数,根据对应的枚举值来转换成关联数据,外部调用直接使用枚举的扩展函数即可:
///对枚举值定义一个扩展函数
extension AnimalEnumExt on AnimalEnum {
///枚举转换int值
int get animalEnumInt {
//扩展函数内部可以直接使用[this]关键字获取当前实例
switch (this) {
case AnimalEnum.dog:
return 101;
case AnimalEnum.cat:
return 102;
case AnimalEnum.chicken:
return 103;
case AnimalEnum.horse:
return 104;
}
}
///枚举转换字符串
String get animalEnumStr {
switch (this) {
case AnimalEnum.dog:
return 'dog';
case AnimalEnum.cat:
return 'cat';
case AnimalEnum.chicken:
return 'chicken';
case AnimalEnum.horse:
return 'horse';
}
}
///枚举转换label
String get animalEnumLabel {
switch (this) {
case AnimalEnum.dog:
return '小狗';
case AnimalEnum.cat:
return '小猫';
case AnimalEnum.chicken:
return '坤坤';
case AnimalEnum.horse:
return '小马';
}
}
///枚举转换声音
String get animalEnumSound {
switch (this) {
case AnimalEnum.dog:
return '汪汪';
case AnimalEnum.cat:
return '喵喵';
case AnimalEnum.chicken:
return '鸡你太美';
case AnimalEnum.horse:
return '吁~';
}
}
}
///业务层调用
///1.手动导如入扩展函数所在的文件包名(这个不太智能)
import 'package:xxxx/AnimalEnumExt.dart';
///2.业务层使用扩展函数
test() {
int enumInt = AnimalEnum.dog.animalEnumInt;
String enumStr = AnimalEnum.dog.animalEnumStr;
String enumLabel = AnimalEnum.dog.animalEnumLabel;
String enumSound = AnimalEnum.dog.animalEnumSound;
}
**场景2:**对枚举关联类型新建扩展函数,根据对应的关联值来转换成关联数据,外部调用直接使用对应类型的扩展函数即可(以枚举int值举例):
///对int值定义一个扩展函数
extension AnimalEnumIntExt on int? {
AnimalEnum? get animalEnum {
switch (this) {
case 101:
return AnimalEnum.dog;
case 102:
return AnimalEnum.cat;
case 103:
return AnimalEnum.chicken;
case 104:
return AnimalEnum.horse;
default:
return null;
}
}
}
///2.业务层使用扩展函数
test() {
int intVar = 101;
AnimalEnum? animalEnum = intVar.animalEnum;
}
3. Flutter3.0:的增强枚举类版本
随着Flutter3.0的发布,google官方对于枚举值进行了一波史诗加强,使enum使用更方便了.
**场景1:**在Flutter3.0发布之后,直接在枚举构造方法内部定义相关属性,枚举值声明处进行声明即可:
///定义一个增强型枚举
enum AnimalEnum {
dog(101, '小狗', '汪汪'),
cat(102, '小猫', '喵喵'),
chicken(103, '坤坤', '鸡你太美'),
horse(104, '小马', '吁~');
const AnimalEnum(this.number, this.label, this.sound);
final int number;
final String label;
final String sound;
}
///业务层调用,直接使用枚举值的属性即可
test() {
int enumInt = AnimalEnum.dog.number;
///name是枚举值自身的get方法,可以直接获取到枚举字符串
String enumStr = AnimalEnum.dog.name;
String enumLabel = AnimalEnum.dog.label;
String enumSound = AnimalEnum.dog.sound;
}
**场景2:**直接在枚举内部定义静态方法,根据属性去匹配查找对应的枚举值:
///定义一个增强型枚举
enum AnimalEnum {
dog(101, '小狗', '汪汪'),
cat(102, '小猫', '喵喵'),
chicken(103, '坤坤', '鸡你太美'),
horse(104, '小马', '吁~');
const AnimalEnum(this.number, this.label, this.sound);
final int number;
final String label;
final String sound;
///通过number属性直接去匹配
static AnimalEnum? getEnumByInt(int enumInt) {
try {
return AnimalEnum.values
.firstWhere((element) => element.number == enumInt);
} catch (e) {
return null;
}
}
///通过Str属性直接去匹配
static AnimalEnum? getEnumByStr(String enumStr) {
try {
//byName是dart2.15版本之后引入的新api,通过字符串去寻找对应的枚举值,注意catch处理
return AnimalEnum.values.byName(enumStr);
} catch (e) {
return null;
}
}
///通过label属性直接去匹配
static AnimalEnum? getEnumByLabel(String enumLabel) {
try {
return AnimalEnum.values
.firstWhere((element) => element.label == enumLabel);
} catch (e) {
return null;
}
}
}
///业务层调用,直接使用枚举内部的静态方法
test1() {
int dogInt = 101;
AnimalEnum? animalEnum0 = AnimalEnum.getEnumByInt(dogInt);
String dogLabel = 'dog';
AnimalEnum? animalEnum1 = AnimalEnum.getEnumByStr(dogLabel);
String doglabel = '小狗';
AnimalEnum? animalEnum2 = AnimalEnum.getEnumByLabel(dogLabel);
}
如理解有误差,请随时批评~