如何在Dart 3.x中创建String枚举?解决编译报错问题
解决Dart中String类型枚举的编译错误
问题重现
习惯在Dart 3.x中设计num类型枚举,创建String类型枚举时沿用旧写法出现两个编译错误:
- 指向枚举值的报错:
The invoked constructor isn't a 'const' constructor. Try invoking a 'const' generative constructor. - 针对工厂构造函数的报错:
The body might complete normally, causing 'null' to be returned, but the return type, 'MonetizationSubscriptionProductId', is a potentially non-nullable type. Try adding either a return or a throw statement at the end.
错误代码如下:
enum MonetizationSubscriptionProductId<String> { /// Premium certified individual subscription kSubscriptionIdPremiumCertifiedIndividuel('premium'), /// Premium certified individual professional subscription kSubscriptionIdPremiumCertifiedProfessional('premium_certified_professional'); const MonetizationSubscriptionProductId(this.value); final String value; factory MonetizationSubscriptionProductId<String>.fromValue(String v) => values.firstWhere((x) => x.value == v, orElse: () => throw Exception("Unknown value $v")); }
用户补充:此前使用的num类型枚举可正常运行,代码示例:
// Smiley size enum SmileySize { small(0), normal(1), large(2); const SmileySize(this.value); final int value; factory SmileySize.fromValue(int v) => values.firstWhere((x) => x.value == v, orElse: () => normal); }
错误原因
- 不必要的泛型声明:Dart枚举不支持自定义泛型参数,你在
MonetizationSubscriptionProductId<String>中添加的<String>是错误用法,这会破坏枚举默认的const构造函数逻辑,导致第一个报错。 - 泛型引发的类型识别问题:由于错误添加了泛型,编译器无法正确解析工厂构造函数的返回类型确定性,从而抛出第二个错误。
修复方案
移除枚举上的泛型声明,直接在成员变量中指定String类型即可:
enum MonetizationSubscriptionProductId { /// Premium certified individual subscription kSubscriptionIdPremiumCertifiedIndividuel('premium'), /// Premium certified individual professional subscription kSubscriptionIdPremiumCertifiedProfessional('premium_certified_professional'); const MonetizationSubscriptionProductId(this.value); final String value; factory MonetizationSubscriptionProductId.fromValue(String v) => values.firstWhere((x) => x.value == v, orElse: () => throw Exception("Unknown value $v")); }
说明
你之前的num类型枚举能正常运行,是因为没有错误添加泛型。Dart枚举的类型由自身定义,不需要额外通过泛型指定关联值的类型,直接在构造函数和成员变量中声明对应类型即可。
内容的提问来源于stack exchange,提问作者Stéphane de Luca
相关产品推荐
相关产品推荐

