Dart 如何将枚举的名称作为字符串获取
Dart How to get the name of an enum as a String
在枚举在 Dart 中可用之前,我写了一些繁琐且难以维护的代码来模拟枚举,现在想简化它。我需要将枚举的名称作为字符串获取,例如可以使用 Java 但不能。
例如小测试代码片段 returns 'day.MONDAY' 在每种情况下我想要的是“星期一”
enum day {MONDAY, TUESDAY}
print( 'Today is $day.MONDAY');
print( 'Today is $day.MONDAY.toString()');
我是否更正了 'MONDAY' 我需要解析字符串?
遗憾的是,您是正确的,toString 方法 returns "day.MONDAY"
,而不是更有用的 "MONDAY"
。
您可以获得字符串的其余部分:
day theDay = day.MONDAY;
print(theDay.toString().substring(theDay.toString().indexOf('.') + 1));
诚然,不太方便。
另一种将枚举名称作为字符串获取的方法是:
theDay.toString().split('.').last
如果性能不重要,那可能就是我要写的内容,只是为了简洁。
如果要迭代所有值,可以使用 day.values
:
for (day theDay in day.values) {
print(theDay);
}
短一点:
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"
我使用如下结构:
abstract 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(Object o) => o.toString().split('.').last;
T enumValueFromString<T>(String key, Iterable<T> values) => values.firstWhere(
(v) => v != null && key == enumValueToString(v),
orElse: () => null,
);
当使用 Dart 2.7 和更新版本时,扩展方法可以在这里工作(以及任何其他对象):
extension EnumX on Object {
String asString() => toString().split('.').last;
}
上面的实现不依赖于特定的枚举。
使用示例:
enum Fruits {avocado, banana, orange}
...
final banana = enumValueFromString('banana', Fruits.values);
print(enumValueToString(banana)); // prints: "banana"
print(banana.asString()); // prints: "banana"
2020-04-05 编辑: 添加了可空性检查。 values
参数可以是 Iterable
,不一定是 List
。添加了扩展方法实现。从示例中删除了 <Fruits>
注释以表明不需要 class 名称重复。
获取枚举名称的最简单方法是 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');
}
我受够了,我做了一个包:
https://pub.dev/packages/enum_to_string
还有一个方便的函数,它接受 enum.ValueOne
并将其解析为“Value one
”
它是一个简单的小库,但经过了单元测试,我欢迎为边缘情况添加任何内容。
我在我的一个项目中遇到了同样的问题,现有的解决方案不是很干净,也不支持像 json serialization/deserialization 这样的高级功能。
Flutter 目前本身不支持带值的枚举,但是,我设法使用 class 和反射器实现开发了一个帮助程序包 Vnum
来克服这个问题。
存储库地址:
https://github.com/AmirKamali/Flutter_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);
}
你可以这样使用它:
var visibility = Visibility('COLLAPSED');
print(visibility.value);
github 存储库中有更多文档,希望对您有所帮助。
Dart 2.7 带有名为 Extension methods 的新功能。现在您可以为 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'
}
我们可以在对象上定义扩展并从任何枚举访问 .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 {MONDAY, TUESDAY}
print(day.toString().split('.')[1]);
OR
print(day.toString().split('.').last);
更新 Dart 2.15:
enum Day {
monday,
tuesday,
}
您可以在枚举上使用 name
属性。
String monday = Day.monday.name; // 'monday'
旧解决方案:
1.直接方式:
var dayInString = describeEnum(Day.monday);
print(dayInString); // prints 'monday'
2。使用扩展名:
extension DayEx on Day {
String get name => describeEnum(this);
}
您可以像这样使用它:
void main() {
Day monday = Day.monday;
print(monday.name); // 'monday'
}
enum day {MONDAY, TUESDAY}
print( 'Today is ${describeEnum(day.MONDAY)}' );
控制台输出:今天是星期一
创建一个class来帮助:
class Enum {
Enum._();
static String name(value) {
return value.toString().split('.').last;
}
}
并调用:
Enum.name(myEnumValue);
有时我需要将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
现在空安全看起来像这样
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;
}
}
你可以看看这个包enum_object
// convert enum value to string
print(TestEnum.test.enumValue);
// convert String to enum value
var enumObject = EnumObject<TestEnum>(TestEnum.values);
print(enumObject.enumFromString('test2'));```
还有一种方法:
enum Length {
TEN,
TWENTY,
THIRTY,
NONE,
}
extension LengthValue on Length {
static const _values = [10, 20, 30, 0];
int get value => _values[this.index];
}
我在答案中找到的一个好方法是
String day = theDay.toString().split('.').last;
但我不建议这样做,因为 dart 为我们提供了更好的方法。
为枚举定义一个扩展名,可能在与以下文件相同的文件中:
enum Day {
monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
extension DayExtension on Day {
String get value => describeEnum(this);
}
你需要为此做 import 'package:flutter/foundation.dart';
。
Dart 2.15 包含一个扩展来简化此操作:
enum day {MONDAY, TUESDAY}
print( 'Today is ${day.MONDAY.name}');
在 https://github.com/dart-lang/sdk/commit/18f37dd8f3db6486f785b2c42a48dfa82de0948b 中的更改推出稳定版本的 Dart 之前,此处其他聪明但更复杂的答案非常有用。
试试这个解决方案:
extension EnumValueToString on Enum {
String valueAsString() {
return describeEnum(this);
}
}
使用方法:
enum.valueAsString()
dart 2.15 现在支持这个
你可以输入
print(day.MONDAY.name); //gives you: MONDAY
从 Dart 2.15 开始,我们可以只做 Day.monday.name
,其中
enum Day { monday, tuesday }
从 Dart 版本 2.15 开始,您可以使用 .name
:
访问 enum
常量的 String
值
enum day {MONDAY, TUESDAY}
void main() {
print('Today is ${day.MONDAY.name}');
// Outputs: Today is MONDAY
}
从 dart 2.15 开始,您可以使用 .name
获取枚举元素的名称。
enum day {MONDAY, TUESDAY}
print(day.MONDAY.name); // prints MONDAY
从 Dart 2.15 开始,您可以从
获取枚举值
print(MyEnum.one.name);
// and for getting enum from value you use
print(MyEnum.values.byName('two');
Dart 版本 2.15
在枚举上引入了 name
属性。
示例
void main() {
MyEnum.values.forEach((e) => print(e.name));
}
enum MyEnum { value1, Value2, VALUE2 }
输出:
value1
Value2
VALUE2
对于需要带值枚举的用户,请使用此方法,因为 Dart 不支持此方法:
class MyEnumClass {
static String get KEY_1 => 'value 1';
static String get KEY_2 => 'value 2';
static String get KEY_3 => 'value 3';
...
}
// Usage:
print(MyEnumClass.KEY_1); // value 1
print(MyEnumClass.KEY_2); // value 2
print(MyEnumClass.KEY_3); // value 3
...
当然你可以输入你需要的任何类型。
在枚举在 Dart 中可用之前,我写了一些繁琐且难以维护的代码来模拟枚举,现在想简化它。我需要将枚举的名称作为字符串获取,例如可以使用 Java 但不能。
例如小测试代码片段 returns 'day.MONDAY' 在每种情况下我想要的是“星期一”
enum day {MONDAY, TUESDAY}
print( 'Today is $day.MONDAY');
print( 'Today is $day.MONDAY.toString()');
我是否更正了 'MONDAY' 我需要解析字符串?
遗憾的是,您是正确的,toString 方法 returns "day.MONDAY"
,而不是更有用的 "MONDAY"
。
您可以获得字符串的其余部分:
day theDay = day.MONDAY;
print(theDay.toString().substring(theDay.toString().indexOf('.') + 1));
诚然,不太方便。
另一种将枚举名称作为字符串获取的方法是:
theDay.toString().split('.').last
如果性能不重要,那可能就是我要写的内容,只是为了简洁。
如果要迭代所有值,可以使用 day.values
:
for (day theDay in day.values) {
print(theDay);
}
短一点:
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"
我使用如下结构:
abstract 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(Object o) => o.toString().split('.').last;
T enumValueFromString<T>(String key, Iterable<T> values) => values.firstWhere(
(v) => v != null && key == enumValueToString(v),
orElse: () => null,
);
当使用 Dart 2.7 和更新版本时,扩展方法可以在这里工作(以及任何其他对象):
extension EnumX on Object {
String asString() => toString().split('.').last;
}
上面的实现不依赖于特定的枚举。
使用示例:
enum Fruits {avocado, banana, orange}
...
final banana = enumValueFromString('banana', Fruits.values);
print(enumValueToString(banana)); // prints: "banana"
print(banana.asString()); // prints: "banana"
2020-04-05 编辑: 添加了可空性检查。 values
参数可以是 Iterable
,不一定是 List
。添加了扩展方法实现。从示例中删除了 <Fruits>
注释以表明不需要 class 名称重复。
获取枚举名称的最简单方法是 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');
}
我受够了,我做了一个包:
https://pub.dev/packages/enum_to_string
还有一个方便的函数,它接受 enum.ValueOne
并将其解析为“Value one
”
它是一个简单的小库,但经过了单元测试,我欢迎为边缘情况添加任何内容。
我在我的一个项目中遇到了同样的问题,现有的解决方案不是很干净,也不支持像 json serialization/deserialization 这样的高级功能。
Flutter 目前本身不支持带值的枚举,但是,我设法使用 class 和反射器实现开发了一个帮助程序包 Vnum
来克服这个问题。
存储库地址:
https://github.com/AmirKamali/Flutter_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);
}
你可以这样使用它:
var visibility = Visibility('COLLAPSED');
print(visibility.value);
github 存储库中有更多文档,希望对您有所帮助。
Dart 2.7 带有名为 Extension methods 的新功能。现在您可以为 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'
}
我们可以在对象上定义扩展并从任何枚举访问 .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 {MONDAY, TUESDAY}
print(day.toString().split('.')[1]);
OR
print(day.toString().split('.').last);
更新 Dart 2.15:
enum Day {
monday,
tuesday,
}
您可以在枚举上使用 name
属性。
String monday = Day.monday.name; // 'monday'
旧解决方案:
1.直接方式:
var dayInString = describeEnum(Day.monday);
print(dayInString); // prints 'monday'
2。使用扩展名:
extension DayEx on Day {
String get name => describeEnum(this);
}
您可以像这样使用它:
void main() {
Day monday = Day.monday;
print(monday.name); // 'monday'
}
enum day {MONDAY, TUESDAY}
print( 'Today is ${describeEnum(day.MONDAY)}' );
控制台输出:今天是星期一
创建一个class来帮助:
class Enum {
Enum._();
static String name(value) {
return value.toString().split('.').last;
}
}
并调用:
Enum.name(myEnumValue);
有时我需要将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
现在空安全看起来像这样
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;
}
}
你可以看看这个包enum_object
// convert enum value to string
print(TestEnum.test.enumValue);
// convert String to enum value
var enumObject = EnumObject<TestEnum>(TestEnum.values);
print(enumObject.enumFromString('test2'));```
还有一种方法:
enum Length {
TEN,
TWENTY,
THIRTY,
NONE,
}
extension LengthValue on Length {
static const _values = [10, 20, 30, 0];
int get value => _values[this.index];
}
我在答案中找到的一个好方法是
String day = theDay.toString().split('.').last;
但我不建议这样做,因为 dart 为我们提供了更好的方法。
为枚举定义一个扩展名,可能在与以下文件相同的文件中:
enum Day {
monday, tuesday, wednesday, thursday, friday, saturday, sunday
}
extension DayExtension on Day {
String get value => describeEnum(this);
}
你需要为此做 import 'package:flutter/foundation.dart';
。
Dart 2.15 包含一个扩展来简化此操作:
enum day {MONDAY, TUESDAY}
print( 'Today is ${day.MONDAY.name}');
在 https://github.com/dart-lang/sdk/commit/18f37dd8f3db6486f785b2c42a48dfa82de0948b 中的更改推出稳定版本的 Dart 之前,此处其他聪明但更复杂的答案非常有用。
试试这个解决方案:
extension EnumValueToString on Enum {
String valueAsString() {
return describeEnum(this);
}
}
使用方法:
enum.valueAsString()
dart 2.15 现在支持这个 你可以输入
print(day.MONDAY.name); //gives you: MONDAY
从 Dart 2.15 开始,我们可以只做 Day.monday.name
,其中
enum Day { monday, tuesday }
从 Dart 版本 2.15 开始,您可以使用 .name
:
enum
常量的 String
值
enum day {MONDAY, TUESDAY}
void main() {
print('Today is ${day.MONDAY.name}');
// Outputs: Today is MONDAY
}
从 dart 2.15 开始,您可以使用 .name
获取枚举元素的名称。
enum day {MONDAY, TUESDAY}
print(day.MONDAY.name); // prints MONDAY
从 Dart 2.15 开始,您可以从
获取枚举值print(MyEnum.one.name);
// and for getting enum from value you use
print(MyEnum.values.byName('two');
Dart 版本 2.15
在枚举上引入了 name
属性。
示例
void main() {
MyEnum.values.forEach((e) => print(e.name));
}
enum MyEnum { value1, Value2, VALUE2 }
输出:
value1
Value2
VALUE2
对于需要带值枚举的用户,请使用此方法,因为 Dart 不支持此方法:
class MyEnumClass {
static String get KEY_1 => 'value 1';
static String get KEY_2 => 'value 2';
static String get KEY_3 => 'value 3';
...
}
// Usage:
print(MyEnumClass.KEY_1); // value 1
print(MyEnumClass.KEY_2); // value 2
print(MyEnumClass.KEY_3); // value 3
...
当然你可以输入你需要的任何类型。