Rust中能否实现嵌套枚举并完成编译期变体合法性检查?
Rust编译期绑定状态与对应阶段的优雅实现
针对你需要在编译期严格绑定角色状态与对应阶段、同时避免代码冗余的需求,最适合的方案是使用Rust宏批量生成状态枚举与对应阶段,既满足编译期类型检查,又能大幅减少重复代码,且完全符合性能要求。
核心实现:宏批量生成状态与阶段
通过自定义宏,可以一键生成每个状态对应的阶段枚举,同时自动将该状态变体加入Condition主枚举,彻底避免状态与阶段不匹配的问题。示例代码如下:
// 定义批量生成状态与阶段的宏 macro_rules! define_condition { ($(#[$meta:meta])* $condition_name:ident => [$($stage:ident),+ $(,)?]) => { // 生成对应状态的阶段枚举 $(#[$meta])* #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum $condition_name { $($stage),+ } // 扩展Condition主枚举,添加当前状态的变体 #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Condition { $condition_name($condition_name), // 递归占位,后续宏调用会自动覆盖扩展 $(define_condition!(@recurse))? } }; // 递归终止的空实现,避免编译报错 (@recurse) => {}; } // 调用宏生成各个状态及对应的阶段 define_condition!(Pregnancy => [FirstTrimester, SecondTrimester, ThirdTrimester]); define_condition!(Cancer => [StageI, StageII, StageIII, StageIVa, StageIVb, StageIVc]); define_condition!(Flu => [Mild, Severe, Recovering]); // 继续添加更多状态... define_condition!(BrokenBone => [Acute, Healing, FullyRecovered]);
方案优势
- 编译期严格检查:每个
Condition变体只能接收对应类型的阶段枚举,完全杜绝Pregnancy绑定CancerStage这类非法组合,无需任何运行时检查。 - 代码简洁无冗余:50-100个状态仅需50-100行宏调用,不会手动编写大量重复的枚举定义,避免命名空间污染。
- 极致性能:所有枚举都实现了
Copy/Clonetrait,处理3-5万个角色时,仅需简单的内存拷贝和枚举匹配,无额外运行时开销。
扩展:统一处理阶段描述
如果需要对所有阶段进行统一操作(比如获取显示描述),可以给所有阶段枚举实现一个共同的trait:
// 定义统一的阶段描述trait trait StageInfo { fn display_name(&self) -> &str; } // 为怀孕阶段实现描述 impl StageInfo for Pregnancy { fn display_name(&self) -> &str { match self { Pregnancy::FirstTrimester => "孕1期", Pregnancy::SecondTrimester => "孕2期", Pregnancy::ThirdTrimester => "孕3期", } } } // 为癌症阶段实现描述 impl StageInfo for Cancer { fn display_name(&self) -> &str { match self { Cancer::StageI => "I期", Cancer::StageII => "II期", Cancer::StageIII => "III期", Cancer::StageIVa => "IVa期", Cancer::StageIVb => "IVb期", Cancer::StageIVc => "IVc期", } } } // 为Condition实现统一调用入口 impl StageInfo for Condition { fn display_name(&self) -> &str { match self { Condition::Pregnancy(stage) => stage.display_name(), Condition::Cancer(stage) => stage.display_name(), Condition::Flu(stage) => match stage { Flu::Mild => "轻度流感", Flu::Severe => "重度流感", Flu::Recovering => "恢复期", }, Condition::BrokenBone(stage) => match stage { BrokenBone::Acute => "骨折急性期", BrokenBone::Healing => "愈合期", BrokenBone::FullyRecovered => "完全康复", }, } } }
内容的提问来源于stack exchange,提问作者user6029609
相关产品推荐
相关产品推荐

