我有一个宏,它接受闭包并将值列表应用于它们。 Clippy 抱怨该代码并发出警告。 MWE:
macro_rules! printit {
($range:expr, $($func:expr),* $(,)?) => {{
for x in $range {
$(println!("{:?} {:?}", x, $func(x));)*
}
}};
}
fn main() {
printit!(
0..10,
|x: u64| x.trailing_zeros(),
|x: u64| x.leading_zeros(),
|x: u64| x.count_ones()
);
}
警告:
warning: try not to call a closure in the expression where it is declared
--> src/main.rs:4:40
|
4 | $(println!("{:?} {:?}", x, $func(x));)*
| ^^^^^^^^
...
10 | / printit!(
11 | | 0..10,
12 | | |x: u64| x.trailing_zeros(),
13 | | |x: u64| x.leading_zeros(),
14 | | |x: u64| x.count_ones()
15 | | );
| |_____- in this macro invocation
它有效。我不知道编译器在抱怨什么。 我该如何编写这个宏来“修复”这个警告?
这是 Clippy 的 redundant_closure_call
-lint 的一个“已知问题”,已经存在了一段时间。目前,在本地简单地
allow
这种模式可能是最简单的。Clippy 正在抱怨,因为宏将扩展为
println!("{:?} {:?}", x, (|x: u64| x.trailing_zeros())(x));
//...
声明闭包然后立即调用,这通常是不必要的。
在宏观扩张的情况下,宏观卫生和这一点存在一些微妙之处;但总的来说,由于疏忽,这个问题似乎没有得到解决。