Enums 飞镖如何获得“飞镖”;“价值”;枚举的
在Dart中提供枚举之前,我编写了一些繁琐且难以维护的代码来模拟枚举,现在我想简化它。我需要以字符串的形式获取枚举的值,例如可以用Java完成,但不能 例如,当我想要的是“星期一”时,小测试代码段在每种情况下都返回“day.MONDAY”Enums 飞镖如何获得“飞镖”;“价值”;枚举的,enums,dart,Enums,Dart,在Dart中提供枚举之前,我编写了一些繁琐且难以维护的代码来模拟枚举,现在我想简化它。我需要以字符串的形式获取枚举的值,例如可以用Java完成,但不能 例如,当我想要的是“星期一”时,小测试代码段在每种情况下都返回“day.MONDAY” 我是否正确,为了得到“星期一”,我需要解析字符串?遗憾的是,您正确地认为toString方法返回的是“day.MONDAY”,而不是更有用的“MONDAY”。 您可以通过以下方式获取字符串的其余部分: day theDay=day.MONDAY; 打印(day
我是否正确,为了得到“星期一”,我需要解析字符串?遗憾的是,您正确地认为toString方法返回的是
“day.MONDAY”
,而不是更有用的“MONDAY”
。
您可以通过以下方式获取字符串的其余部分:
day theDay=day.MONDAY;
打印(day.toString().substring(theDay.toString().indexOf('.')+1));
无可否认,这很不方便
另一种将枚举名称获取为字符串的方法是,该方法较短,但效率较低,因为它也会为字符串的第一部分创建一个不必要的字符串:
theDay.toString().split('.').last
如果性能不重要,我可能会这么写,只是为了简洁
如果要迭代所有值,可以使用day.values
:
for(day中的day.values){
打印(当日);
}
稍微短一点:
String day = theDay.toString().split('.').last;
有一个更优雅的解决方案:
enum SomeStatus {
element1,
element2,
element3,
element4,
}
const Map<SomeStatus, String> SomeStatusName = {
SomeStatus.element1: "Element 1",
SomeStatus.element2: "Element 2",
SomeStatus.element3: "Element 3",
SomeStatus.element4: "Element 4",
};
print(SomeStatusName[SomeStatus.element2]) // prints: "Element 2"
enum SomeStatus{
要素1,
要素2,
要素3,
要素4,
}
常量映射SomeStatusName={
SomeStatus.element1:“元素1”,
SomeStatus.element2:“元素2”,
SomeStatus.element3:“元素3”,
SomeStatus.element4:“Element 4”,
};
print(SomeStatusName[SomeStatus.element2])//打印:“Element 2”
我使用如下结构:
class Strings {
static const angry = "Dammit!";
static const happy = "Yay!";
static const sad = "QQ";
}
我的方法没有本质上的不同,但在某些情况下可能会稍微方便一些:
enum Day {
monday,
tuesday,
}
String dayToString(Day d) {
return '$d'.split('.').last;
}
在Dart中,您无法自定义枚举的toString
方法,因此我认为此辅助函数解决方案是必要的,也是最好的方法之一。如果您希望在这种情况下更准确,可以将返回字符串的第一个字母改为大写
您还可以添加一个dayFromString
函数
Day dayFromString(String s) {
return Day.values.firstWhere((v) => dayToString(v) == s);
}
用法示例:
void main() {
Day today = Day.monday;
print('Today is: ${dayToString(today)}');
Day tomorrow = dayFromString("tuesday");
print(tomorrow is Day);
}
我使用以下函数获取枚举值的名称,反之亦然,通过名称获取枚举值:
String enumValueToString(对象o)=>o.toString().split('.').last;
T enumValueFromString(字符串键,Iterable值)=>values.firstWhere(
(v) =>v!=null&&key==enumValueToString(v),
orElse:()=>null,
);
当使用Dart 2.7及更新版本时,扩展方法将在此处(以及任何其他对象)起作用:
对象上的扩展EnumX{
字符串asString()=>toString().split('.').last;
}
上述实现不依赖于特定的枚举
用法示例:
enum水果{鳄梨、香蕉、橘子}
...
final banana=enumValueFromString('banana',Fruits.values);
打印(enumValueToString(香蕉));//打印:“香蕉”
print(banana.asString());//prints:“banana”
从2020年4月5日开始编辑:添加了可空性检查。
值可以是Iterable
,不一定是List
。添加了扩展方法实现。从示例中删除了
注释,以表明不需要复制类名。获取枚举名称的最简单方法是sta颤振/基础.dart的标准方法
describeEnum(enumObject)
enum Day {
monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
void validateDescribeEnum() {
assert(Day.monday.toString() == 'Day.monday');
assert(describeEnum(Day.monday) == 'monday');
}
我受够了,我做了一个包裹:
还有一个方便的函数,可以获取enum.ValueOne
并将其解析为“ValueOne
”
这是一个简单的小库,但经过了单元测试,我欢迎为edge案例添加任何内容。我在一个项目中遇到了相同的问题,现有的解决方案不是很干净,它不支持json序列化/反序列化等高级功能
flatter本机目前不支持带有值的enum,但是,我设法使用类和反射器实现开发了一个helper包Vnum
,以克服这个问题
存储库地址:
要使用Vnum
回答您的问题,您可以实现以下代码:
@VnumDefinition
class Visibility extends Vnum<String> {
static const VISIBLE = const Visibility.define("VISIBLE");
static const COLLAPSED = const Visibility.define("COLLAPSED");
static const HIDDEN = const Visibility.define("HIDDEN");
const Visibility.define(String fromValue) : super.define(fromValue);
factory Visibility(String value) => Vnum.fromValue(value,Visibility);
}
github repo中有更多文档,希望能对您有所帮助。Dart 2.7附带了名为的新功能。现在,您可以编写自己的枚举方法,就这么简单
enum Day { monday, tuesday }
extension ParseToString on Day {
String toShortString() {
return this.toString().split('.').last;
}
}
main() {
Day monday = Day.monday;
print(monday.toShortString()); //prints 'monday'
}
我们不必为每个枚举定义扩展,而是可以在对象上定义扩展,并从任何枚举访问.enumValue
void main() {
// ❌ Without Extension ❌
print(Countries.Cote_d_Ivoire.toString().split('.').last.replaceAll("_", " ")); // Cote d Ivoire
print(Movies.Romance.toString().split('.').last.replaceAll("_", " ")); //Romance
// ✅ With Extension ✅
print(Countries.Cote_d_Ivoire.enumValue); // Cote d Ivoire
print(Movies.Romance.enumValue); //Romance
}
enum Countries { United_States, United_Kingdom, Germany, Japan, Cote_d_Ivoire }
enum Movies { Romance, Science_Fiction, Romantic_Comedy, Martial_arts }
extension PrettyEnum on Object {
String get enumValue => this.toString().split('.').last.replaceAll("_", " ");
}
有了它,您甚至可以定义多单词枚举,其中单词在其名称中用
(下划线)分隔。enum Day{
enum day {MONDAY, TUESDAY}
print(day.toString().split('.')[1]);
OR
print(day.toString().split('.').last);
星期一,
星期二,
}
直接方式:
var dayInString=descripbeenum(Day.monday);
打印(dayInString);//打印“星期一”
使用扩展名:
日扩展日{
字符串get inString=>descripbeenum(这个);
}
您可以像这样使用它:
void main(){
Day monday=Day.monday;
字符串inString=monday.inString;//“monday”
}
控制台输出:今天是星期一创建一个类来帮助:
class Enum {
Enum._();
static String name(value) {
return value.toString().split('.').last;
}
}
并致电:
Enum.name(myEnumValue);
有时我需要将ui值和实际值分开,所以我使用Map
定义了键和值。这样,我们就有了更大的灵活性。通过使用扩展
(从Dart 2.7开始),我创建了一种读取键和值的方法
enum Status {
progess,
done,
}
extension StatusExt on Status {
static const Map<Status, String> keys = {
Status.progess: 'progess',
Status.done: 'done',
};
static const Map<Status, String> values = {
Status.progess: 'In Progress',
Status.done: 'Well done',
};
String get key => keys[this];
String get value => values[this];
// NEW
static Status fromRaw(String raw) => keys.entries
.firstWhere((e) => e.value == raw, orElse: () => null)
?.key;
}
// usage 1
Status status = Status.done;
String statusKey = status.key; // done
String statusValue = status.value; // Well done
// usage 2 (easy to make key and value list)
List<Status> statuses = Status.values;
List<String> statusKeys = statuses.map((e) => e.key).toList();
List<String> statusValues = statuses.map((e) => e.value).toList();
// usage 3. create Status enum from string.
Status done1 = StatusExt.fromRaw('done') // Status.done
Status done2 = StatusExt.fromRaw('dude') // null
enum状态{
进步,
完成,
}
扩展状态EXT on状态{
静态常量映射键={
Status.proges:“proges”,
Status.done:'done',
};
静态常量映射值={
Status.proges:“正在进行中”,
Status.done:“干得好”,
};
字符串get key=>keys[this];
字符串get value=>values[this];
//新的
静态状态fromRaw(stringraw)=>keys.entries
.firstWhere((e)=>e.value==raw,或lse:()=>null)
钥匙
}
//用法1
Status Status=Status.done;
字符串statusKey=status.key;//完成
字符串状态
class Enum {
Enum._();
static String name(value) {
return value.toString().split('.').last;
}
}
Enum.name(myEnumValue);
enum Status {
progess,
done,
}
extension StatusExt on Status {
static const Map<Status, String> keys = {
Status.progess: 'progess',
Status.done: 'done',
};
static const Map<Status, String> values = {
Status.progess: 'In Progress',
Status.done: 'Well done',
};
String get key => keys[this];
String get value => values[this];
// NEW
static Status fromRaw(String raw) => keys.entries
.firstWhere((e) => e.value == raw, orElse: () => null)
?.key;
}
// usage 1
Status status = Status.done;
String statusKey = status.key; // done
String statusValue = status.value; // Well done
// usage 2 (easy to make key and value list)
List<Status> statuses = Status.values;
List<String> statusKeys = statuses.map((e) => e.key).toList();
List<String> statusValues = statuses.map((e) => e.value).toList();
// usage 3. create Status enum from string.
Status done1 = StatusExt.fromRaw('done') // Status.done
Status done2 = StatusExt.fromRaw('dude') // null
String enumToString(Object? o) => o != null ? o.toString().split('.').last : '';
T? enumFromString<T>(String key, List<T> values) {
try {
return values.firstWhere((v) => key == enumToString(v));
} catch(e) {
return null;
}
}
// convert enum value to string
print(TestEnum.test.enumValue);
// convert String to enum value
var enumObject = EnumObject<TestEnum>(TestEnum.values);
print(enumObject.enumFromString('test2'));```