如何解决宏中“尽量不要在声明它的表达式中调用闭包”?

问题描述 投票:0回答:1

我有一个宏,它接受闭包并将值列表应用于它们。 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

它有效。我不知道编译器在抱怨什么。 我该如何编写这个宏来“修复”这个警告?

rust macros
1个回答
0
投票

这是 Clippy 的 redundant_closure_call-lint 的一个“已知问题”,已经存在了一段时间。目前,在本地简单地

allow
这种模式可能是最简单的。
Clippy 正在抱怨,因为宏将扩展为

println!("{:?} {:?}", x, (|x: u64| x.trailing_zeros())(x)); //...

声明闭包然后立即调用,这通常是不必要的。

在宏观扩张的情况下,宏观卫生和这一点存在一些微妙之处;但总的来说,由于疏忽,这个问题似乎没有得到解决。

© www.soinside.com 2019 - 2024. All rights reserved.