我想编写一个打印“OK”然后在方法中返回self的宏。这是我的第一个宏,所以我尝试了这个,认为它会像文本替换一样,但它失败了:
macro_rules! print_ok_and_return_self {
() => {
println!("OK");
self
}
}
fn main() {
let a = A{};
a.a().a();
}
struct A {}
impl A {
fn a(self) -> Self {
print_ok_and_return_self!()
}
}
错误:
error: macro expansion ignores token `self` and any following
--> src/main.rs:4:13
|
4 | self
| ^^^^
|
note: caused by the macro expansion here; the usage of `print_ok_and_return_self!` is likely invalid in expression context
--> src/main.rs:17:13
|
17| print_ok_and_return_self!()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
快速查看文档后,我知道这不仅仅是文本替换,但我仍然不知道如何使其工作。
答案 0 :(得分:13)
连续出现两个错误,让我们修复第一个错误。
宏臂的语法是:
(...) => {
...
}
这意味着你的宏花费的是:
println!("OK");
self
哪个不好(两个陈述)。
相反,它应该扩展为一个表达式(在这种情况下),你可以将它括在{}
中:
macro_rules! print_ok_and_return_self {
() => {
{
println!("OK");
self
}
}
}
这导致第二个错误:
error[E0424]: `self` is not available in a static method
--> <anon>:4:9
|
4 | self
| ^^^^ not available in static method
...
17 | print_ok_and_return_self!()
| --------------------------- in this macro invocation
|
= note: maybe a `self` argument is missing?
宏不能假设其范围内存在变量,因此您需要将self
作为参数传递:
macro_rules! print_ok_and_return_value {
($v:expr) => {{
println!("OK");
$v
}}
}
,调用变为:
impl A {
fn a(self) -> Self {
print_ok_and_return_value!(self)
}
}