将类型作为标识传递给 macro_rules 时,“没有规则需要令牌`<`”

use*_*932 2 rust

玩具示例:

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

tre*_*tcl 6

$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 书的第一版有一个关于宏的章节,包括可能的片段说明符列表;在尝试编写宏之前,您绝对应该熟悉本章的内容。