Rust宏与传递的类型不匹配

dra*_*tis 4 macros rust

直接传递给宏模式的类型与您期望的方式匹配,但如果它们通过另一个宏传递,则它们会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));
}
Run Code Online (Sandbox Code Playgroud)

这打印ioo而不是iiz.

传递tts代替tys工作,但是如果&str你需要2 tt秒,使一切变得不必要地复杂化.

DK.*_*DK. 7

这不起作用,无法工作.

总结一下Rust Macros小书Captures和Expansion Redux章节:问题是除了ttident捕获之外,macro_rules!完全无法解构或检查捕获的令牌.一旦你捕获了某些东西ty,它就会不可逆转地成为一个黑盒子macro_rules!.

换句话说:就其而言,它&str不是一种类型macro_rules!:它是两个令牌,&而且str.但是当你捕获然后替换&strty,它变成了一个"元令牌":类型&str.两者不再相同,因此不匹配.

如果您打算稍后匹配或破坏令牌,则必须将其捕获为tts或idents(如果可能).在这种特定情况下,您可以重写规则,around而不是($($t:tt)*) => (mrtype!($($t)*));保留原始令牌序列.