You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中带共用Mixin的未知枚举类型与字符串互转方案

可行的实现方案

针对你的需求,我们可以分别实现enumToString和stringToEnum,以下是具体方案:


一、enumToString 实现

这个方法非常直接:传入的枚举实例同时实现了TestMixin,只需将其转换为TestMixin类型后获取value即可:

String enumToString(Enum inp) {
  return (inp as TestMixin).value;
}

二、stringToEnum 实现

这里提供两种方案,适配不同场景:

方案1:手动注册枚举类型(无依赖、简单直接)

Dart没有内置机制自动收集所有使用TestMixin的枚举,我们可以手动维护一个包含目标枚举的列表,遍历查找匹配值:

// 全局维护所有带TestMixin的枚举values集合
final List<Iterable<Object>> _registeredEnums = [
  FirstEnum.values,
  SecondEnum.values,
  // 新增枚举时,只需在这里添加对应的.values
];

Enum stringToEnum(String inp) {
  for (final enumValues in _registeredEnums) {
    for (final value in enumValues) {
      if (value is TestMixin && value.value == inp) {
        return value as Enum;
      }
    }
  }
  throw ArgumentError('未找到值为 "$inp" 的枚举');
}

优点:无需额外依赖,代码简洁,运行性能好。
缺点:新增枚举时需要手动添加到注册列表。

方案2:使用reflectable反射(自动收集枚举,需依赖)

如果想避免手动注册,可以用reflectable反射库自动扫描带指定注解的枚举,步骤如下:

  1. 添加依赖
    在pubspec.yaml中添加:
dependencies:
  reflectable: ^4.0.0

dev_dependencies:
  build_runner: ^2.4.0
  1. 创建反射配置
    新建reflector.dart文件:
import 'package:reflectable/reflectable.dart';

class EnumReflector extends Reflectable {
  const EnumReflector() : super(
    invokingCapability,
    declarationsCapability,
  );
}

const enumReflector = EnumReflector();
  1. 为枚举添加注解
    在每个带TestMixin的枚举类上标注@enumReflector:
@enumReflector
enum FirstEnum with TestMixin {
  foo("bar");

  const FirstEnum(this.value);
  @override
  final String value;
}

@enumReflector
enum SecondEnum with TestMixin {
  two("car");

  const SecondEnum(this.value);
  @override
  final String value;
}
  1. 生成反射代码
    运行命令生成反射相关文件:
dart run build_runner build
  1. 实现stringToEnum
import 'reflector.dart';
import 'reflector.reflectable.dart'; // 生成的反射文件

// 初始化反射(需在使用前调用,比如main函数开头)
void initializeReflectors() {
  initializeReflectable();
}

Enum stringToEnum(String inp) {
  for (final type in enumReflector.annotatedClasses) {
    if (type.isEnum) {
      // 获取枚举的values列表
      final values = type.invokeGetter('values') as List<Object>;
      for (final enumValue in values) {
        if (enumValue is TestMixin && enumValue.value == inp) {
          return enumValue as Enum;
        }
      }
    }
  }
  throw ArgumentError('未找到值为 "$inp" 的枚举');
}

优点:新增枚举时只需添加注解,无需手动维护列表。
缺点:引入第三方依赖,需要运行构建命令,运行性能略低于手动注册方案。


注意事项

  • 必须保证所有枚举的value值唯一,否则stringToEnum会返回第一个匹配的枚举值,导致逻辑错误。
  • 可根据需求修改stringToEnum的错误处理逻辑,比如返回null而非抛出异常。

内容的提问来源于stack exchange,提问作者Flojomojo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:33:11