enum
添加成员。在Dart中是否也可以这样做?enum Foo {
one(1), two(2);
final num value;
Foo(this.value);
}
enum
添加成员。在Dart中是否也可以这样做?enum Foo {
one(1), two(2);
final num value;
Foo(this.value);
}
从 Dart 2.6 开始,您可以在类上定义扩展(包括枚举)。
enum Cat {
black,
white
}
extension CatExtension on Cat {
String get name {
switch (this) {
case Cat.black:
return 'Mr Black Cat';
case Cat.white:
return 'Ms White Cat';
default:
return null;
}
}
void talk() {
print('meow');
}
}
例子:
Cat cat = Cat.black;
String catName = cat.name;
cat.talk();
这里是另一个实时示例(使用常量映射而不是 switch 语句):https://dartpad.dartlang.org/c4001d907d6a420cafb2bc2c2507f72c
enum X{a, b};
在定义扩展后将具有 3 个条目。即 enum X{a, b, c}
类似于 extension MyEnum on X{ /* 在此处修改值 */ }
。 - Phani Rithvij从Dart 2.17开始,引入了增强枚举类功能。因此,问题中的示例将如下所示:
enum Foo {
one(1),
two(2);
const Foo(this.value);
final num value;
}
void main() {
const foo = Foo.one;
print(foo.value); // 1
}
environment:
sdk: '>=2.17.0-0 <3.0.0'
使用增强型枚举,只要构造函数为const
,您就可以向枚举中添加任何成员。
这也意味着您可以向现有的枚举中添加getter或方法,例如:
enum Cake {
cherry,
apple,
strawberry;
String get description => '$name cake';
}
增强型枚举类还允许您在枚举中使用泛型。如果将其与成员结合使用,您可以执行以下操作:
enum Bar<T extends Object> {
number<int>(42),
name<String>('creativecreatorormaybenot'),
baz(true); // Note that type inference also works.
const Bar(this.value);
final T value;
}
除了声明成员外,你还可以使用增强的枚举来混入 mixins 和实现接口,并覆盖任何缺失的实现。
mixin Foo {
int get n;
}
abstract class Bar {
void printNumber();
}
enum Baz with Foo implements Bar {
one(1),
two(2);
const Baz(this.n);
@override
final int n;
@override
void printNumber() => print(n);
}
最后请注意,即使我在上面的任何示例中都没有使用它,也可以拥有任意数量的参数(和初始化列表):
enum Foo {
bar(42, description: 'The answer to life, the universe, and everything.'),
baz(0, enabled: false, description: 'noop');
const Foo(
int number, {
this.enabled = true,
required this.description,
}) : n = number;
final int n;
final bool enabled;
final String description;
}
Dart 枚举仅适用于最简单的情况。如果您需要更强大或更灵活的枚举,请使用类并添加静态常量字段,如https://dev59.com/XGUo5IYBdhLWcg3wrhBD#15854550 中所示。
这样您就可以添加任何您需要的内容。
switch
结合使用,如果您没有涵盖所有枚举值,则会发出警告。您是否知道是否有一种方法可以通过自定义类实现此行为?该方法是为了维护性目的。 - Rémi Rousselet不可以。在Dart中,枚举只能包含枚举的项:
enum Color {
red,
green,
blue
}
然而,枚举类型中的每个项都自动与一个索引号相关联:
print(Color.red.index); // 0
print(Color.green.index); // 1
print(Color.values[0] == Color.red); // True
参见:https://www.dartlang.org/guides/language/language-tour#enums
MyEnum.values
就是我一直想要的,再加上扩展方法就足够了。 - om-ha可能不符合"Effective Dart"标准,我在Helper类中添加了一个静态方法(Dart中没有伴生对象)。
在你的color.dart
文件中。
enum Color {
red,
green,
blue
}
class ColorHelper{
static String getValue(Color color){
switch(color){
case Color.red:
return "Red";
case Color.green:
return "Green";
case Color.blue:
return "Blue";
default:
return "";
}
}
}
由于该方法与枚举在同一文件中,所以一个导入就足够了
import 'package:.../color.dart';
...
String colorValue = ColorHelper.getValue(Color.red);
我做了这个(受到@vovahost的接受答案的启发)
enum CodeVerifyFlow {
SignUp, Recovery, Settings
}
extension CatExtension on CodeVerifyFlow {
String get name {
return ["sign_up", "recovery", "settings"][index];
}
}
// use it like
CodeVerifyFlow.SignUp.name
扩展是有用的,但它不能添加静态方法。如果您想做像 MyType.parse(string) 这样的操作,请考虑使用带有静态const字段的类,而不是扩展(如Günter Zöchbauer之前建议的那样)。
以下是一个例子
class PaymentMethod {
final String string;
const PaymentMethod._(this.string);
static const online = PaymentMethod._('online');
static const transfer = PaymentMethod._('transfer');
static const cash = PaymentMethod._('cash');
static const values = [online, transfer, cash];
static PaymentMethod parse(String value) {
switch (value) {
case 'online':
return PaymentMethod.online;
break;
case 'transfer':
return PaymentMethod.transfer;
break;
case 'cash':
return PaymentMethod.cash;
default:
print('got error, invalid payment type $value');
return null;
}
}
@override
String toString() {
return 'PaymentMethod.$string';
}
}
final method = PaymentMethod.parse('online');
assert(method == PaymentMethod.online);
parse
方法,但是它只能通过 ExtensionName.parse()
调用,这对最终用户来说不太可发现。我会更新我的答案以指出这一点。 - Bouke Versteeghconst Map<String, PaymentMethod>
中,在解析时只返回该键的值,并返回null或抛出错误。请参阅此处:https://gist.github.com/boukeversteegh/f67e58f500f3c0c7126640bb43e11197 - Bouke Versteeghenum Blah {
one(1), two(2);
final num value;
const Blah(this.value);
}
该功能尚未发布(请注意,有几个问题尚未解决),但是可以通过使用新版本的工具并传递--enable-experiment=enhanced-enums
来进行实验。
结果是Blah
是一个枚举声明,其包含两个值Blah.one
和Blah.two
,且Blah.one.value == 1
和Blah.two.value == 2
。当前的“开发版本”在常见的前端处理此示例(因此dart
和dart2js
将处理它),但分析器尚未处理。
enum Numbers {
one,
two,
three,
}
// Numbers.one.value == 1
// Numbers.two.value == 2
// Numbers.three.value == 3
带有列表的示例
extension NumbersExtensionList on Numbers {
static const values = [1, 2, 3];
int get value => values[this.index];
}
使用地图的示例
extension NumbersExtensionMap on Numbers {
static const valueMap = const {
Numbers.one: 1,
Numbers.two: 2,
Numbers.three: 3,
};
int get value => valueMap[this];
}
注意:这种方法的限制是您无法在枚举上定义一个静态工厂方法,例如
Numbers.create(1)
(截至Dart 2.9)。您可以在NumbersExtension
上定义此方法,但需要像NumbersExtension.create(1)
那样调用。
对于字符串的返回:
enum Routes{
SPLASH_SCREEN,
HOME,
// TODO Add according to your context
}
String namedRoute(Routes route){
final runtimeType = '${route.runtimeTypes.toString()}.';
final output = route.toString();
return output.replaceAll(runtimeType, "");
}