我正在尝试实现一个实现结构的Add trait的宏,如下所示:
macro_rules! implement_add {
($t:ty) => {
impl std::ops::Add for $t {
type Output = $t;
fn add(self, rhs: $t) -> $t {
$t(self.0 + rhs.0) // error on this line
}
}
}
}
pub struct Length(f64);
implement_add!(Length);
fn main() {}
但是,这会在指定的行上出现错误:
<anon>:6:17: 6:19 error: unexpected token: `Length`
<anon>:6 $t(self.0 + rhs.0) // error on this line
^~
这对我没有意义。特别是因为,如果我用$t
替换Length
,那么它编译得很好。我在宏观中做错了吗?
答案 0 :(得分:4)
你偶然发现了Rust的一个微妙的类型系统。 Length
是一种类型,但Length()
是函数。它们存在于不同的名称空间中。
一种解决方法是将宏扩展为接受和类型的函数:
macro_rules! implement_add {
($t:ty, $c:ident) => {
impl std::ops::Add for $t {
type Output = $t;
fn add(self, rhs: $t) -> $t {
$c(self.0 + rhs.0) // error on this line
}
}
}
}
pub struct Length(f64);
implement_add!(Length, Length);
fn main() {}