宏
宏是一种为写其他代码而写代码的方式,即所谓的元编程。宏在编译器翻译代码前展开。
声明宏
使用 marco_rules! 的声明宏用于通用元编程。
#![allow(unused)] fn main() { #[macro_export] // 表明只要导入了该crate就可以使用该宏 macro_rules! my_vec { // macro_rules! 定义宏 vec 宏名称 ($($x:expr),*) => { // 与 match 类似,$x:expr 表示匹配一个表达式,$()表示重复,*表示重复0次或多次 { let mut temp_vec = Vec::new(); $( temp_vec.push($x); )* temp_vec } }; } }
过程宏
他们接受一个代码作为输入,在这些代码上进行操作,然后产生另一些代码作为输出。而非像声明宏那样匹配对应模式然后以另一部分代码替换当前代码。
有三种类型的过程宏: 自定义派生(derive)宏
#![allow(unused)] fn main() { }
类属性宏
可以创建新的属性。
#![allow(unused)] fn main() { #[route(GET, '/index')] fn index() {} #[proc_macro_attribute] pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {} }
类函数(Function-Like)宏 看起来像函数调用的宏
#![allow(unused)] fn main() { let sql = sql!(SELECT * FROM posts WHERE id=1); #[proc_macro] pub fn sql(input: TokenStream) -> TokenStream {} }