简介
在本实验中,我们将介绍 Rust 宏中的指示符概念。指示符用于在宏的参数前加上前缀,并进行类型注释。指示符的一些示例包括用于变量/函数名的 ident、用于表达式的 expr、用于代码块的 block 以及用于模式的 pat。这些指示符在宏规则中用于根据提供的参数生成代码。
注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用
main.rs,并通过rustc main.rs &&./main进行编译和运行。
在本实验中,我们将介绍 Rust 宏中的指示符概念。指示符用于在宏的参数前加上前缀,并进行类型注释。指示符的一些示例包括用于变量/函数名的 ident、用于表达式的 expr、用于代码块的 block 以及用于模式的 pat。这些指示符在宏规则中用于根据提供的参数生成代码。
注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用
main.rs,并通过rustc main.rs &&./main进行编译和运行。
宏的参数以美元符号 $ 为前缀,并使用一个 指示符 进行类型注释:
macro_rules! create_function {
// 此宏接受一个 `ident` 指示符类型的参数,并
// 创建一个名为 `$func_name` 的函数。
// `ident` 指示符用于变量/函数名。
($func_name:ident) => {
fn $func_name() {
// `stringify!` 宏将一个 `ident` 转换为字符串。
println!("你调用了 {:?}()",
stringify!($func_name));
}
};
}
// 使用上述宏创建名为 `foo` 和 `bar` 的函数。
create_function!(foo);
create_function!(bar);
macro_rules! print_result {
// 此宏接受一个 `expr` 类型的表达式,并打印
// 它及其结果的字符串形式。
// `expr` 指示符用于表达式。
($expression:expr) => {
// `stringify!` 将按原样把表达式转换为字符串。
println!("{:?} = {:?}",
stringify!($expression),
$expression);
};
}
fn main() {
foo();
bar();
print_result!(1u32 + 1);
// 记住,代码块也是表达式!
print_result!({
let x = 1u32;
x * x + 2 * x - 1
});
}
以下是一些可用的指示符:
blockexpr 用于表达式ident 用于变量/函数名itemliteral 用于字面常量pat(模式)pathstmt(语句)tt(标记树)ty(类型)vis(可见性限定符)有关完整列表,请参阅 [Rust 参考手册]。
恭喜你!你已完成“指示符”实验。你可以在 LabEx 中练习更多实验来提升你的技能。