2016-02-21 74 views
4

類型直接傳遞給宏模式相匹配你所期望的方式,但如果他們通過另一個宏傳遞了作爲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作品,但如果你有&str需要2個tt S,使一切不必要的複雜。

回答

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。兩者不再一樣,因此不匹配。

如果您打算以後比賽反對或解構令牌,你必須捕捉它們作爲tt S或ident S(如果可能)。在此特定的情況下,您可以將around的規則重寫爲($($t:tt)*) => (mrtype!($($t)*));,該規則保留了原始標記序列。