Macros Rust宏与传递的类型不匹配

Macros Rust宏与传递的类型不匹配,macros,rust,Macros,Rust,直接传递到宏模式的类型与您期望的方式匹配,但如果它们作为ty传递到另一个宏,则它们将停止匹配: macro_rules! mrtype { ( bool ) => ("b"); ( i32 ) => ("i"); ( f64 ) => ("f"); ( &str ) => ("z"); ( $_t:ty ) => ("o"); } macro_rules! around { ( $t:ty

直接传递到宏模式的类型与您期望的方式匹配,但如果它们作为
ty
传递到另一个宏,则它们将停止匹配:

macro_rules! mrtype {
    ( bool )   => ("b");
    ( i32 )    => ("i");
    ( f64 )    => ("f");
    ( &str )   => ("z");
    ( $_t:ty ) => ("o");
}

macro_rules! around {
    ( $t:ty ) => (mrtype!($t));
}

fn main() {
    println!("{}{}{}", mrtype!(i32), around!(i32), around!(&str));
}
这将打印
ioo
,而不是
iiz


传递
tt
s而不是
ty
s是有效的,但是如果你有
&str
你需要2个
tt
s,这会使一切变得不必要的复杂。

这不起作用,也无法让它发挥作用

总结一下:问题是除了
tt
ident
捕获之外,
宏规则完全无法分解或检查捕获的令牌。一旦您将某个内容捕获为
ty
,它就不可撤销地成为
宏规则的黑匣子

换句话说:
&str
宏规则而言不是一种类型
关注的是:它是两个令牌,
&
str
。但是,当您捕获并将
&str
替换为
ty
时,它将成为一个“元标记”:类型
&str
。两者不再相同,因此不再匹配

如果您打算稍后匹配或分解令牌,则必须将它们捕获为
tt
s或
ident
s(如果可能)。在这种特定情况下,您可以将
的规则改写为
($($t:tt)*)=>(mrtype!($($t)*)),保留原始令牌序列