怎么在Dart 3.x中创建一个字符串枚举?

huangapple go评论52阅读模式
英文:

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&lt;String&gt; {
  /// Premium certified individual subscription
  kSubscriptionIdPremiumCertifiedIndividuel(&#39;premium&#39;),

  /// Premium certified individual professional subscription
  kSubscriptionIdPremiumCertifiedProfessional(&#39;premium_certified_professional&#39;);

  const MonetizationSubscriptionProductId(this.value);

  final String value;

  factory MonetizationSubscriptionProductId&lt;String&gt;.fromValue(String v) =&gt;
      values.firstWhere((x) =&gt; x.value == v,
          orElse: () =&gt; throw Exception(&quot;Unknown value $v&quot;));
}

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) =&gt;
      values.firstWhere((x) =&gt; x.value == v, orElse: () =&gt; 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(&#39;premium&#39;),

  /// Premium certified individual professional subscription
  kSubscriptionIdPremiumCertifiedProfessional(&#39;premium_certified_professional&#39;);

  const MonetizationSubscriptionProductId(this.value);

  final String value;
}

MonetizationSubscriptionProductId mapValueToMonetizationSubscriptionProductId(String v) =&gt;
    MonetizationSubscriptionProductId.values.firstWhere(
      (x) =&gt; x.value == v,
      orElse: () =&gt; throw Exception(&quot;Unknown value $v&quot;),
    );

答案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) =&gt;
      values.firstWhere((x) =&gt; x.value == v,
          orElse: () =&gt; throw Exception(&quot;Unknown value $v&quot;));

  @override
  String toString() {
    switch (this) {
      case kSubscriptionIdPremiumCertifiedIndividuel:
        return &#39;premium&#39;;
      case kSubscriptionIdPremiumCertifiedProfessional:
        return &#39;premium_certified_professional&#39;;
    }
  }
}

huangapple
  • 本文由 发表于 2023年5月7日 18:27:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76193358.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定