我正在尝试在Rust宏中匹配struct
。我需要拉
struct
彼此分开以获得其名称。我发现那个街区
匹配者可以解决问题。例如,考虑一下:
macro_rules! multi {
(struct $name:ident $block:block) => {
enum George {$name}
}
}
multi!{
struct Fred {
a:String
}
}
扩展为
enum George { Fred, }
大约是正确的。
但是,如果我将其改回struct
,它将失败。
macro_rules! multi {
(struct $name:ident $block:block) => {
struct $name $block
}
}
出现此错误。
error: expected `where`, `{`, `(`, or `;` after struct name, found `{ a: String }`
--> src/main.rs:64:22
|
64 | struct $name $block
| ^^^^^^ expected `where`, `{`, `(`, or `;` after struct name
似乎{a: String}
被视为单个令牌,而不是
而不是重新解析;但这应该是在那里。
答案 0 :(得分:2)
$:block
匹配器用于块表达式,即一组包含零个或多个Rust语句和项目以及可选的尾随返回值的花括号。例如,以下是块:
{
let x = 1;
}
{
#[derive(Default)]
struct S;
S::default()
}
Rust中大括号的示例是块
if
和else
子句,for
,while
和loop
循环的循环体。结构字段周围的花括号不是一个块,因为它们不应包含零个或多个Rust语句和项目,后跟可选的尾随返回值。相反,它们应该包含struct字段的名称和类型。
在宏中,您可以使用{ $($tt:tt)* }
模式匹配任意一组花括号,这意味着“包含任意数量的任意标记的花括号”。
macro_rules! multi {
(struct $name:ident { $($tt:tt)* }) => {
struct $name { $($tt)* }
};
}
multi! {
struct Fred {
a: String,
}
}