rust宏定义

发布时间:2026/7/11 14:25:54
rust宏定义 Rust 宏的核心理念宏的本质在编译时生成代码的代码生成器就像你在写代码时有些模式会反复出现宏就是帮你自动生成这些重复代码的工具。宏的三大类型及其作用1.声明宏Declarative Macros-macro_rules!作用模式匹配 代码展开// 最常见的vec! 宏letvvec![1,2,3];// 展开成letv{letmuttempVec::new();temp.push(1);temp.push(2);temp.push(3);temp};// 自定义例子计算平方macro_rules!square{($x:expr){$x*$x};}letresultsquare!(5);// 展开成 5 * 5典型用途println!、format!- 格式化输出vec!、HashMap!- 快速创建集合assert!、panic!- 断言和错误处理简化重复的模式匹配代码2.过程宏Procedural MacrosA.派生宏Derive Macros-#[derive(...)]作用自动实现 trait// 你的例子就是这个类型#[derive(Debug, Clone, Serialize, UpdateKeep)]structUser{name:String,#[keep]created_at:String,}典型用途#[derive(Debug)]- 自动实现调试输出#[derive(Clone)]- 自动实现克隆#[derive(Serialize)]- 自动实现 JSON 序列化serde自定义的 derive 宏就像你的UpdateKeepB.属性宏Attribute Macros-#[...]作用修改或增强函数、结构体、模块等// 1. 测试标记#[test]fntest_function(){...}// 2. Web 框架路由#[get(/user/{id})]fnget_user(id:u64){...}// 3. 条件编译#[cfg(target_os windows)]fnwindows_only(){...}// 4. 异步标记#[async_trait]traitMyTrait{...}典型用途测试框架#[test]Web 框架Actix、Rocket 的路由依赖注入日志记录自动添加日志C.函数式宏Function-like Macros-macro!()作用像函数一样调用但处理的是 TokenStream// 看起来像函数但功能强大letsqlsql!(SELECT * FROM users WHERE id ?,1);// 可以在编译时验证 SQL 语法lethtmlhtml!{divpHello{name}/p/div};// 在编译时检查 HTML 结构letregexregex!(r^\d{3}-\d{4}$);// 在编译时编译正则表达式典型用途嵌入 DSL领域特定语言编译时计算复杂的字符串处理宏 vs 函数核心区别特性宏函数执行时机编译时运行时输入TokenStreamRust 代码值输出Rust 代码值灵活性可以接受任意语法结构只能接受类型化的参数复杂度更复杂更简单举例说明差异// 函数只能接受具体类型fnadd(a:i32,b:i32)-i32{ab}// 宏可以接受任意类型的表达式macro_rules!add{($a:expr,$b:expr){$a$b};}// 可以这样用add!(1,2)// i32add!(1.5,2.5)// f64add!(a,b)// 编译错误但函数做不到这个检查实际应用场景总结1.减少样板代码// 没有宏手动实现每个方法implUser{fnget_name(self)-String{self.name}fnget_age(self)-u32{self.age}// ... 100 个 getter}// 有宏一行搞定#[derive(Getters)]structUser{name:String,age:u32}2.编译时验证// 编译时检查 SQL 语法letquerysql!(SELECT * FROM users WHERE id $1,user_id);// 如果 SQL 语法错误编译失败// 编译时检查正则表达式letreregex!(r^[a-z]$);// 如果正则表达式无效编译失败3.DSL领域特定语言// HTML 模板lethtmlhtml!{ul{users.iter().map(|user|html!{li{user.name}/li})}/ul};// 路由定义router!{GET/home,POST/loginlogin,}4.性能优化// 编译时计算constCOMPUTED:i32compute!(123);// 编译时就算好了// 内联展开letresultlazy!(expensive_function());// 按需执行你的宏在这个体系中的位置你的UpdateKeep属于过程宏 → 派生宏作用自动为结构体生成update方法解决的问题减少手动实现更新逻辑的重复代码安全保证用#[keep]标记保护敏感字段总结Rust 宏的本质在编译时操纵代码的工具声明宏模式匹配生成代码简单、常见派生宏自动实现 traitORM、序列化属性宏修改代码行为路由、测试函数式宏编译时计算/验证SQL、正则宏让 Rust 既能保持底层性能又能拥有高级语言的表达能力——写一次生成多次。