什么是宏 | 宏是编译时自动生成代码的技术。 比喻:想象一下,你在做饭时有一个食谱,这个食谱告诉你一步一步做菜。宏就像一个食谱,它告诉计算机如何生成一段代码 |
宏的类型 | 1.声明式宏 作用:让你用一种模板的方法生成代码,可以把它想象成填空题 例子: macro_rules! max { ($x:expr, $y:expr) => { if $x > $y { $x } else { $y } }; } let m = max!(3, 5); // 输出结果将是 5 在这个例子中 max!就是一个填空题,你只需要填两个数字,它就会帮你生成一个if语句来比较两个数字,并返回较大的那个 |
2.程序式宏 作用:可以生成rust代码的函数,可以把它想象成一个“智能食谱”,这个食谱不仅告诉你怎么做菜,还能根据不同的食材自动调整做法 例子: // 引入必要的 crate extern crate proc_macro; use proc_macro::TokenStream; use quote::quote; use syn::parse_macro_input; #[proc_macro_derive(Counter)] //标记表明这是一个过程宏 用于派生(derive)宏,并且它的关联的宏的名称是Counter pub fn derive_counter(input: TokenStream) -> TokenStream { // 解析输入的结构体定义 let input = parse_macro_input!(input as syn::DeriveInput); //将输入的 TokenStream 解析为 syn::DeriveInput 类型 // 根据解析得到的信息生成代码 let name = &input.ident; let gen = quote! { //quote! 宏用于生成 Rust 代码 impl #name { //生成了一个 impl 块,这个块为结构体实现了一个名为 count_fields 的方法 fn count_fields() -> usize { // 返回结构体字段的数量 5 // 假设结构体有五个字段 } } }; // 返回生成的代码 将生成的代码转换回 TokenStream 并返回它 gen.into() } #[derive(Counter)] //告诉 Rust 编译器使用我们定义的 Counter 过程宏来为 MyStruct 结构体生成代码 struct MyStruct { field1: u32, field2: String, // ...更多字段 } | |
如何使用宏 | 1.直接调用: max!(3, 5) 2.作为属性:#[derive(Counter)] 作为结构体定义的一部分 |
使用宏的注意事项 | 1.错误信息不友好:宏是在编译中运行的,如果宏有错误,错误信息可能不如rust代码那么清晰 2.过度使用造成复杂性 |
rust学习_宏
于 2024-09-18 09:42:40 首次发布