在Dart中提供枚举之前,我写了一些繁琐且难以维护的代码来模拟枚举,现在想要简化它.我需要将枚举的值作为字符串获取,例如可以用Java完成,但不能.
例如,当我想要的是"星期一"时,小测试代码片段在每种情况下返回'day.MONDAY'
enum day {MONDAY, TUESDAY}
print( 'Today is $day.MONDAY');
print( 'Today is $day.MONDAY.toString()');
Run Code Online (Sandbox Code Playgroud)
我是否更正为了得到'星期一'我需要解析字符串?
mba*_*rtn 150
Dart 2.7 带有称为扩展方法的新功能。现在您可以为 Enum 编写自己的方法,就这么简单!
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'
}
Run Code Online (Sandbox Code Playgroud)
Jan*_*sen 34
短一点:
String day = theDay.toString().split('.').last;
Run Code Online (Sandbox Code Playgroud)
lrn*_*lrn 25
遗憾的是,你是正确的,toString方法返回"day.MONDAY",而不是更有用"MONDAY".您可以将其余字符串作为:
day theDay = day.MONDAY;
print("${theDay.toString().substring(theDay.toString().indexOf('.')+1)}");
Run Code Online (Sandbox Code Playgroud)
诚然,这很方便.
如果要迭代所有值,可以使用以下命令day.values:
for (day theDay in day.values) {
print(theDay);
}
Run Code Online (Sandbox Code Playgroud)
Cop*_*oad 25
enum Day {
monday,
tuesday,
}
Run Code Online (Sandbox Code Playgroud)
直接方式:
var dayInString = describeEnum(Day.monday);
print(dayInString); // prints 'monday'
Run Code Online (Sandbox Code Playgroud)
使用扩展:
extension DayEx on Day {
String get inString => describeEnum(this);
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
void main() {
Day monday = Day.monday;
String inString = monday.inString; // 'monday'
}
Run Code Online (Sandbox Code Playgroud)
gbi*_*hue 19
获取枚举名称的最简单方法是flutter / foundation.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');
}
Run Code Online (Sandbox Code Playgroud)
小智 19
enum day {MONDAY, TUESDAY}
print( 'Today is ${describeEnum(day.MONDAY)}' );
Run Code Online (Sandbox Code Playgroud)
控制台输出:今天是星期一
小智 12
有一个更优雅的解决方案:
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"
Run Code Online (Sandbox Code Playgroud)
jit*_*555 12
如https://medium.com/dartlang/dart-2-17-b216bfc80c5d中所述:
在Dart 2.17中,我们现在对枚举成员有了普遍支持。这意味着我们可以添加保存状态的字段、设置该状态的构造函数、具有功能的方法,甚至覆盖现有成员。
例子:
enum Day {
MONDAY("Monday"),
TUESDAY("Tuesday");
const Day(this.text);
final String text;
}
Run Code Online (Sandbox Code Playgroud)
输出:
void main() {
const day = Day.MONDAY;
print(day.text); /// Monday
}
Run Code Online (Sandbox Code Playgroud)
对于上述功能,覆盖 dart 版本,如下所示,目标为 2.17 及更高版本
environment:
sdk: ">=2.17.0 <3.0.0"
Run Code Online (Sandbox Code Playgroud)
有时我需要将 ui-value 和 real-value 分开,所以我使用Map. 这样,我们就有了更多的灵活性。通过使用extension(自 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
Run Code Online (Sandbox Code Playgroud)
我使用下面的函数来获取枚举值的名称,反之亦然,通过名称获取枚举值:
String enumValueToString(Object o) => o.toString().split('.').last;
T enumValueFromString<T>(String key, Iterable<T> values) => values.firstWhere(
(v) => v != null && key == enumValueToString(v),
orElse: () => null,
);
Run Code Online (Sandbox Code Playgroud)
当使用 Dart 2.7 和更新版本时,扩展方法将在这里工作(以及任何其他对象):
extension EnumX on Object {
String asString() => toString().split('.').last;
}
Run Code Online (Sandbox Code Playgroud)
上面的实现不依赖于特定的枚举。
用法示例:
enum Fruits {avocado, banana, orange}
...
final banana = enumValueFromString('banana', Fruits.values);
print(enumValueToString(banana)); // prints: "banana"
print(banana.asString()); // prints: "banana"
Run Code Online (Sandbox Code Playgroud)
2020 年 4 月 5 日编辑:添加了可空性检查。values参数可能是Iterable,不一定是List。添加了扩展方法实现。<Fruits>从示例中删除了注释以表明不需要类名重复。
Dart 2.15 包含一个扩展,可以让这一切变得简单:
enum day {MONDAY, TUESDAY}
print( 'Today is ${day.MONDAY.name}');
Run Code Online (Sandbox Code Playgroud)
在https://github.com/dart-lang/sdk/commit/18f37dd8f3db6486f785b2c42a48dfa82de0948b中的更改推出到 Dart 的稳定版本之前,这里的其他聪明但更复杂的答案非常有用。
我克服了这个我做了一个包:
https://pub.dev/packages/enum_to_string
还有一个方便的函数,可以enum.ValueOne将其解析为“ Value one”
它是一个简单的小库,但它经过了单元测试,我欢迎为边缘情况添加任何内容。
小智 6
从 dart 2.15 开始只使用“.name”
enum day {monday, tuesday}
print( 'Today is ${day.monday.name}');
Run Code Online (Sandbox Code Playgroud)
我使用如下结构:
class Strings {
static const angry = "Dammit!";
static const happy = "Yay!";
static const sad = "QQ";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17207 次 |
| 最近记录: |