英文:
How to craft a String enum in Dart 3.x?
问题
enum MonetizationSubscriptionProductId {
  /// Premium certified individual subscription
  kSubscriptionIdPremiumCertifiedIndividuel('premium'),
  /// Premium certified individual professional subscription
  kSubscriptionIdPremiumCertifiedProfessional('premium_certified_professional');
  const MonetizationSubscriptionProductId(this.value);
  final String value;
  String get enumValue => value;
}
英文:
I'm used to design num enums in Dart 3.x, but there, I need a String enum.
I tried to do the same as before but I get compilers issues which I don't know how to solve:
> The invoked constructor isn't a 'const' constructor.
Try invoking a 'const' generative constructor.
This error points to each enum value.
And that one for the factory:
>The body might complete normally, causing 'null' to be returned, but the return type, 'MonetizationSubscriptionProductId<String>', is a potentially non-nullable type.
Try adding either a return or a throw statement at the end.
My code is as follows:
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"));
}
UPDATE: Regarding the "You can't have factory constructors for enums.", see the working code I usually use for my enums.
// 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);
}
答案1
得分: 1
以下是您要翻译的内容:
"MonetizationSubscriptionProductId" 的通用类型似乎不是必需的。这些枚举字段与它们的通用类型没有关联(事实上,我无法想出通用枚举的任何用例;如果您有任何用例,那将很有趣)。
如果您想要拥有 "fromValue" 函数,我建议创建一个顶级方法或一个静态函数(不要放在枚举内部,这样不会起作用)。
总之,也许您正在寻找像这样的内容:
enum MonetizationSubscriptionProductId {
  /// 高级认证个人订阅
  kSubscriptionIdPremiumCertifiedIndividuel('premium'),
  /// 高级认证个人专业订阅
  kSubscriptionIdPremiumCertifiedProfessional('premium_certified_professional');
  const MonetizationSubscriptionProductId(this.value);
  final String value;
}
MonetizationSubscriptionProductId mapValueToMonetizationSubscriptionProductId(String v) =>
    MonetizationSubscriptionProductId.values.firstWhere(
      (x) => x.value == v,
      orElse: () => throw Exception("未知值 $v"),
    );
英文:
The generic type for MonetizationSubscriptionProductId doesn't seem necessary. The enum fields aren't tied to their generic type (in fact, I couldn't come up with any use cases for generic enums; if you have any, it would be interesting to know).
If you want to have the fromValue function, I suggest creating a top-level method or a static function (not inside the enum itself, though; it won't work).
To put it all together, perhaps something like this is what you're looking for:
enum MonetizationSubscriptionProductId {
  /// Premium certified individual subscription
  kSubscriptionIdPremiumCertifiedIndividuel('premium'),
  /// Premium certified individual professional subscription
  kSubscriptionIdPremiumCertifiedProfessional('premium_certified_professional');
  const MonetizationSubscriptionProductId(this.value);
  final String value;
}
MonetizationSubscriptionProductId mapValueToMonetizationSubscriptionProductId(String v) =>
    MonetizationSubscriptionProductId.values.firstWhere(
      (x) => x.value == v,
      orElse: () => throw Exception("Unknown value $v"),
    );
答案2
得分: -1
After remark of @f-person and giving a second thought, there is no need to actually have the enum to be String-based.
Just do what I usually do and use the toString() to set the actual product ID I need, as follows:
enum MonetizationSubscriptionProductId {
  /// Premium certified individual subscription
  kSubscriptionIdPremiumCertifiedIndividuel(0),
  /// Premium certified individual professional subscription
  kSubscriptionIdPremiumCertifiedProfessional(1);
  const MonetizationSubscriptionProductId(this.value);
  final num value;
  factory MonetizationSubscriptionProductId.fromValue(num v) =>
      values.firstWhere((x) => x.value == v,
          orElse: () => throw Exception("Unknown value $v"));
  @override
  String toString() {
    switch (this) {
      case kSubscriptionIdPremiumCertifiedIndividuel:
        return 'premium';
      case kSubscriptionIdPremiumCertifiedProfessional:
        return 'premium_certified_professional';
    }
  }
}
英文:
After remark of @f-person and giving a second thought, there is no need to actually have the enum to be String-based.
Just do what I usually do and use the toString() to set the actual product ID I need, as follows:
enum MonetizationSubscriptionProductId {
  /// Premium certified individual subscription
  kSubscriptionIdPremiumCertifiedIndividuel(0),
  /// Premium certified individual professional subscription
  kSubscriptionIdPremiumCertifiedProfessional(1);
  const MonetizationSubscriptionProductId(this.value);
  final num value;
  factory MonetizationSubscriptionProductId.fromValue(num v) =>
      values.firstWhere((x) => x.value == v,
          orElse: () => throw Exception("Unknown value $v"));
  @override
  String toString() {
    switch (this) {
      case kSubscriptionIdPremiumCertifiedIndividuel:
        return 'premium';
      case kSubscriptionIdPremiumCertifiedProfessional:
        return 'premium_certified_professional';
    }
  }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论