玩具示例:
macro_rules! boo {
($T:ident) => {
let x: $T;
};
}
fn main() {
boo!(i32); // WORKS
boo!(Option<i32>); // PROBLEM
}
Run Code Online (Sandbox Code Playgroud)
boo!(Option<i32>); 导致错误:
macro_rules! boo {
($T:ident) => {
let x: $T;
};
}
fn main() {
boo!(i32); // WORKS
boo!(Option<i32>); // PROBLEM
}
Run Code Online (Sandbox Code Playgroud)
我可以解决它:
type Opti32 = Option<i32>;
boo!(Opti32);
Run Code Online (Sandbox Code Playgroud)
但是为宏的每次使用添加别名太无聊了。是否可以使用像这样的宏boo!(Option<i32>);并将困难隐藏在里面macro_rules?
$T:ident只能匹配一个ident标识符。
如果你想$T匹配任何type,即使它不是一个单一的标识符,你也应该使用$T:ty:
macro_rules! boo {
($T:ty) => {
let x: $T;
}
}
Run Code Online (Sandbox Code Playgroud)
ident并且ty被称为“片段说明符”,因为它们指定元变量$T可以匹配的代码片段类型。Rust 书的第一版有一个关于宏的章节,包括可能的片段说明符列表;在尝试编写宏之前,您绝对应该熟悉本章的内容。