如何编写Rust宏为枚举数组生成构建器方法?
解决方案
首先,你的枚举名Option会和标准库的std::option::Option冲突,建议先重命名为MyOption:
enum MyOption { A, B(String), C(usize), } #[derive(Default)] struct Options { options: Vec<MyOption>, }
接下来可以编写自定义宏生成所需的构建器方法,核心逻辑是遍历枚举的所有变体,为Options结构体生成对应的链式方法——每个方法会将枚举变体推入内部的options向量,并返回self以支持链式调用:
macro_rules! generate_option_builders { ($struct_name:ident, $enum_name:ident, $( $variant:ident $(($arg_ty:ty))? ),*) => { impl $struct_name { $( fn $variant(&mut self $(, arg: $arg_ty)?) -> &mut Self { self.options.push($enum_name::$variant $(arg)?); self } )* } }; } // 调用宏生成方法 generate_option_builders!(Options, MyOption, A, B(String), C(usize));
现在就能实现你想要的链式调用效果了:
fn main() { let mut opts = Options::default() .a() .b(String::from("Hey")) .c(123); // 验证生成的集合内容 assert_eq!(opts.options.len(), 3); }
关于derive_builder的适用性
derive_builder这类 crate 主要用于为结构体的字段生成构建器(比如为每个字段生成set_xxx方法),而你的需求是向结构体内部的向量中添加枚举变体,属于定制化的方法生成场景,derive_builder无法直接满足,自定义宏是更直接的解决方案。
内容的提问来源于stack exchange,提问作者Matheus Richard
相关产品推荐
相关产品推荐

