Dart中如何根据枚举索引自动映射枚举值到对应JsonValue
解决方案
完全不需要手动给每个枚举值添加@JsonValue注解,以下两种方案都可以直接基于枚举自身index完成自动映射,按需选择即可。
方案1:全局配置json_serializable默认枚举映射规则
如果你使用官方json_serializable库做JSON序列化,直接在项目根目录的build.yaml中添加全局配置,即可让所有无自定义映射规则的枚举默认按index匹配int类型的JSON值:
targets: $default: builders: json_serializable: options: # 枚举默认按index和数值做映射 enumFieldNaming: index
配置完成后执行dart run build_runner build重新生成序列化代码,你的ActionStatus枚举不需要加任何注解,就能自动实现0->none、1->done、2->failed、3->skipped的映射,和手动加@JsonValue的效果完全一致。
- 注意:该配置为全局生效,如果某个枚举有特殊映射需求,单独给对应枚举值加
@JsonValue就会覆盖默认规则,不会产生冲突。
方案2:通用枚举Index转换器
如果你不想修改全局配置,需要更灵活的局部控制,可以实现一个通用的JsonConverter,只需要给需要按index映射的枚举添加一次注解,不需要逐个写枚举值的映射:
- 先写通用转换器,支持所有继承自
Enum的类型:
class EnumIndexConverter<T extends Enum> implements JsonConverter<T, int> { const EnumIndexConverter(this.values); final List<T> values; @override T fromJson(int json) { // 增加边界容错,避免后端传非法值导致运行时报错 if (json < 0 || json >= values.length) { // 可根据业务需求调整默认返回值,或抛出自定义业务异常 return values.first; } return values[json]; } @override int toJson(T instance) => instance.index; }
- 使用时只需要给对应枚举添加转换器注解即可:
@EnumIndexConverter(ActionStatus.values) enum ActionStatus { none, done, failed, skipped, }
如果不想给枚举加注解,也可以直接在序列化模型的枚举字段上添加该注解,效果一致。
注意事项
- 两种方案都要求枚举值的声明顺序和后端约定的int编码顺序完全一致,后续新增枚举值必须追加在枚举列表末尾,不要在中间插入,否则会出现映射错位。
- 如果枚举存在不连续的特殊编码值,单独给对应值加
@JsonValue即可,不会影响其他值的自动映射逻辑。
内容的提问来源于stack exchange,提问作者Adam Smaka
相关产品推荐
相关产品推荐

