假设我想让以下宏起作用:
macro_rules! process_numbers {
($name:ident, $process:expr) => {
let $name: Vec<_> = vec![0, 1, 2].iter().map(|num| {
println!("{}", path); // dummy preprocessing
let foo = 3; // some other preprocessing involving side-effects
$process
}).collect();
}
}
process_numbers!(name, {
num + foo
});
Run Code Online (Sandbox Code Playgroud)
有没有办法让我可以从内部num访问?foo$process
Rust 宏是卫生的。这意味着宏体内定义的标识符不会泄漏出去。
\n解决此问题的一种方法是修改宏,使其接收标识符作为参数。
\nmacro_rules! process_numbers {\n ($name:ident, |$num:ident, $foo: ident| $process:expr) => {\n let $name: Vec<_> = vec![0, 1, 2].iter().map(|$num| {\n println!("{}", path); // dummy preprocessing\n let $foo = 3; // some other preprocessing involving side-effects\n $process\n }).collect();\n }\n}\n\nprocess_numbers!(name, |num, foo| {\n num + foo\n});\nRun Code Online (Sandbox Code Playgroud)\n在这里,我使用的语法看起来像一个闭包,这表明|num, foo|声明参数(它们实际上声明变量 \xe2\x80\x93 足够接近!)。
另一种方法是使$process参数成为宏将调用的文字闭包(或任何可调用表达式),传递num和foo作为参数传递。
macro_rules! process_numbers {\n ($name:ident, $process:expr) => {\n let $name: Vec<_> = vec![0, 1, 2].iter().map(|num| {\n println!("{}", path); // dummy preprocessing\n let foo = 3; // some other preprocessing involving side-effects\n $process(num, foo)\n }).collect();\n }\n}\n\nprocess_numbers!(name, |num, foo| {\n num + foo\n});\nRun Code Online (Sandbox Code Playgroud)\n