我的应用程序连接到一个自定义的外设,并从中提取一些值作为整型,我想将其转换为枚举,以简化应用程序代码。
随着硬件的不断发展,新的价值将会出现,这是众所周知的。
在我的Flutter应用程序中,我通过枚举扩展处理已知值(在编写应用程序时),提供如下"未知"值:
// Battery live data originator protocol
enum BatteryLiveDataProtocol {
unknown, // 0
rs485, // 1
ttl, // 2
canbus, // 3
uart, //4
;
}
extension BatteryLiveDataProtocolExtension on BatteryLiveDataProtocol {
/// Build the enum out of the int number
static BatteryLiveDataProtocol fromNumber(int number) {
switch (number) {
case 1:
return ttl;
case 2:
return rs485;
case 3:
return canbus;
case 0:
default:
return unknown;
}
}
/// Returns the number correpsonding to the enum
int get number {
switch (this) {
case rs485:
return 1;
case ttl:
return 2;
case canbus:
return 3;
case unknown:
default:
return 0;
}
}
可以看到,这段代码非常方便地支持未来版本:
const futureValue = 13;
final p = BatteryLiveDataProtocol.fromNumber(futureValue);
问世以来的飞镖2.17 (,3)我想利用增强的枚举如下:
// Battery live data originato protocol
enum BatteryLiveDataProtocol {
unknown(),
rs485(1),
ttl(2),
canbus(3),
uart(4),
;
const BatteryLiveDataProtocol(this.value);
final num value;
}
那么我如何处理未来的枚举值呢?
我可以这样做,只要我想把整型转换成enum:
BatteryLiveDataProtocol p;
try {
const futureValue = 13;
p = BatteryLiveDataProtocol(futureValue);
} catch(e) {
p = BatteryLiveDataProtocol.unknown;
}
但是这很麻烦,不是吗?如果有可能自己提供const BatteryLiveDataProtocol(this.value);
的身体,那将是一件很酷的事情。
static BatteryLiveDataProtocol fromValue(int v) {
BatteryLiveDataProtocol p;
try {
p = BatteryLiveDataProtocol[v];
} catch (e) {
p = unknown;
}
return p;
}
并按如下方式使用:
const futureValue = 13;
final p = BatteryLiveDataProtocol.fromValue(futureValue);
// Makes p being set to "unknown".
所以我的问题#1:有没有更好/聪明(又名方便)的方法来处理未来的值?
问题#2:其他语言处理未来枚举(在Swift中例如):是否有一种方法来生成unknown(actualValue)
作为一个动态枚举值?
所以我的问题#1:是否有更好/聪明(又名方便)的方法来处理未来的值?
我认为您可以通过将fromNumber
和number
的定义移到枚举本身而不是作为扩展来改进枚举。
另外,我认为你可以改进fromNumber
和number
的实现。
对于number
,枚举已经有一个名为index的getter,它返回的值与您想要的值相同,因此您可以简单地在number
方法中返回index
。
对于fromNumber
,我们可以将其转换为工厂构造函数,并且由于所有枚举都有一个静态的values
列表(其中包含所有枚举值按其定义的特定顺序),我们可以通过索引values
列表来获得我们想要的值。对于任何无效索引,我们将返回unknown
。
对number
和fromNumber
进行这些更改的好处是,当您添加另一个enum值时,您将不再需要更新这些方法。
更新后的enum如下:
enum BatteryLiveDataProtocol {
unknown, // 0
rs485, // 1
ttl, // 2
canbus, // 3
uart, //4
;
factory BatteryLiveDataProtocol.fromNumber(int number) =>
number >= values.length || number < 0 ? unknown : values[number];
int get number => index;
}
问题#2:其他语言处理未来enum(例如在Swift中):是否有一种方法来生成
unknown(actualValue)
作为动态enum值?
不,dart的增强枚举不像swift枚举那样工作,dart中的枚举更接近java枚举。Swift调用这个特性的关联值,但是dart枚举没有这个特性。
感谢@mmcdon20提供的工厂建议(顺便说一句,我无法在下面的代码中用factory
替换static
)。
但是要确保一个处理任何值:值和索引可能不同,正如我下面提出的修改示例中,unknown
的value
现在设置为-1
(index
是0
)。
所以代码必须处理它:
/// Battery live data originato protocol
enum BatteryLiveDataProtocol {
unknown(-1),
rs485(1),
ttl(2),
canbus(3),
uart(4),
;
const BatteryLiveDataProtocol(this.value);
final num value;
factory BatteryLiveDataProtocol.fromValue(int v) =>
values.firstWhere((x) => x.value == v, orElse: () => unknown);
}