宏
Rust大约 2 分钟...
宏是 Rust 中强大的元编程工具,允许编写可以生成其他代码的代码。宏和函数类似,但末尾有一个!
,它们在编译时展开成源代码
声明宏
声明式宏使用macro_rules!
定义,类似于模式匹配
macro_rules! hello {
() => {
println!("hello");
}
}
fn main() {
hello!()
}
匹配多种情况
和 match 一样可以匹配多种情况
macro_rules! six_or_print {
(6) => {
6
};
() => {
println!("You didn't give me 6.");
};
}
fn main() {
let six = six_or_print!(6);
six_or_print!();
}
捕获和使用输入
可以将任何内容设置为宏的输入,有多种捕获方式:
特定模式匹配
macro_rules! might_print {
(THis is strange input 하하はは哈哈 but it still works) => {
println!("You guessed the secret message!")
};
() => {
println!("You didn't guess it");
};
}
fn main() {
might_print!(THis is strange input 하하はは哈哈 but it still works);
might_print!();
}
表达式捕获,宏可以理解提供的不同输入,对于expr
给它一个变量$input
macro_rules! might_print {
($input:expr) => {
println!("You gave me: {:?}", $input);
};
}
fn main() {
might_print!(());
might_print!(6);
might_print!(vec![1, 2, 3]);
}
多个标识符
macro_rules! check {
($input1:ident, $input2:expr) => {
println!(
"Is {:?} equal to {:?}? {:?}",
$input1,
$input2,
$input1 == $input2
);
};
}
fn main() {
let x = 6;
let my_vec = vec![7, 8, 9];
check!(x, 6);
check!(my_vec, vec![7, 8, 9]);
check!(x, 10);
}
重复模式
使用 * 或 + 可以匹配零个或多个,或者一个或多个重复模式
macro_rules! vector {
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(
temp_vec.push($x);
)*
temp_vec
}
};
}
fn main() {
let v = vector![1, 2, 3];
println!("{:?}", v);
}
静态检查
函数则不具备字符串格式化的静态检查功能,而宏可以更好地进行检查
println!("number1 {} number2 {}"); // 应该接受两个参数用于内部填充
过程宏
过程宏更加强大,可以操作输入的 Rust 代码。有三种类型的过程宏:
- 派生宏(Derive macros)
- 属性宏(Attribute-like macros)
- 函数式宏(Function-like macros)
内置宏和编译期计算
Rust 提供了许多内置宏,如 println!, vec!, format! 等,一些宏可以在编译期进行计算
println!("File: {}, line: {}", file!(), line!());
println!("This code is compiled for: {}", std::env::consts::OS);