Rust宏与传递的类型不匹配

时间:2016-02-21 12:44:29

标签: 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));
}

这会打印ioo而不是iiz

传递tt而不是ty,但如果您&str,则需要2 tt秒,这会让所有内容变得不必要。

1 个答案:

答案 0 :(得分:7)

这不起作用,无法工作。

总结Captures and Expansion Redux chapter of The Little Book of Rust Macros:问题在于ttident抓取除外,macro_rules!完全无法解构或检查捕获的令牌。一旦你捕捉到ty的内容,它就会不可逆转地成为macro_rules!的黑盒子。

换句话说:&str不是一种类型,就macro_rules!而言:它是两个令牌,&str。但是,当您捕获并将&str替换为ty时,它将成为单个“元令牌”:类型&str。两者不再相同,因此不匹配。

如果您打算稍后匹配或破坏令牌,则必须将其捕获为ttident s(如果可能)。在此特定的情况下,您可以将around的规则改为($($t:tt)*) => (mrtype!($($t)*));,而不是%USERPROFILE%\AppData\Roaming\npm,这会保留原始令牌序列。