这是一个非常小的问题,我知道如何禁用警告,但仔细阅读它,我怀疑它可能表明我的宏可能做了一些不正确的事情.无论如何,我有一个用于有理数的 struct Rational
:
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Rational {
n: i128,
d: i128,
}
impl Rational {
pub fn new(n: i128, d: i128) -> Self {
Rational { n, d }
}
}
为了以一种可读的方式创建这些代码,我使用宏:
macro_rules! rat {
($whole: tt $n : tt / $d : tt) => {
crate::rational::Rational::new($n + $whole * $d, $d)
};
($n : tt / $d : tt) => {
crate::rational::Rational::new($n, $d)
};
($n : tt) => {
crate::rational::Rational::new($n, 1)
};
}
以及一些代码来测试和演示这一点:
let x = 42;
println!("{}", rat!(1));
println!("{}", rat!(2 / 3));
println!("{}", rat!(x));
println!("{}", rat!(x / 2));
println!("{}", rat!(2 / x));
println!("{}", rat!(x 1/2));
println!("{}", rat!(1 4/5));
println!("{}", rat!((5 / 1) / 2)); //this line shows a warning
希望在这里你能(某种程度上)看到宏的意义--用一个普通的函数调用,像1/2
这样的东西在被函数看到之前就会崩溃到0
.(顺便说一句,我知道为了单一的有理数这样做是不值得的,但我认为这可能是为了快速解析更大的等式,比如equation!(1/2 x + 3 3/4 y + 24 z = 2 3/4 + 4 x)
.这只是迈向这一目标的一小步.)
不管怎样,实际的问题是:在最后一个例子中,它抱怨说5/1
左右的括号是不必要的.然而,如果我删除它们(println!("{}", rat!(5 / 1 / 2));
),宏会失败,并返回"在宏调用中没有规则需要这个令牌".)(顺便说一句,这个测试显然语法不好,我只是想确保它可以处理任意表达式.)
所以,有两个问题:
- 这是不是我在构建这些宏时风格不佳的结果?
- 有没有一种方法可以禁用这个警告,它不仅比通用的
#![allow(unused_parens)]
更具体,而且也不需要在每个调用点调用它?(我想知道是否可以以某种方式将Allow烘焙到宏本身,尽管我认为这没有意义.)
编辑:我发现问题不在于调用,而在于生成的代码--花括号对宏来说是必需的,Ruust认识到了这一点,但随后宏输出new((5/1), 2)
,其中花括号实际上是不必要的.我不确定处理这一问题的正确方式,尽管我看到了一些 Select .