macro_rules! m {
(1) => { print!("1") };
($tt:tt) => { print!("2") };
}
macro_rules! e {
($e:expr) => { m!($e) };
}
macro_rules! t {
($tt:tt) => { e!($tt); m!($tt); };
}
fn main() {
t!(1);
}
和一些泛型型別方法呼叫類似,不同場景下回轉換為不同的型別。
在macro_rules
裡面,也會有這種現象。
相關的型別轉換和直接透傳的型別如下
型別轉換
$:block
$:expr
$:item
$:literal
$:meta
$:pat
$:path
$:stmt
$:ty
型別透傳
$:ident
$:lifetime
$:tt
m!
macro_rules! m { (1) => { print!("1") }; ($tt:tt) => { print!("2") }; }
這裡的主要問題,就是傳入的是什麼資料。
如果是數值1
,沒問題肯定列印的是1
,如果是tt
呢,那就列印2
。e!
macro_rules! e { ($e:expr) => { m!($e) }; }
這裡匹配了
expr
,然後傳入m!
。
但是expr
隱藏有型別轉換的功能,因此傳入之後,並非直接數值1
了。
而是token-1
。t!
macro_rules! t { ($tt:tt) => { e!($tt); m!($tt); }; }
這裡,有直接的判斷列印
m!
,還有一箇中間型別轉換e!
。
由於傳入的是1
,如果是直接呼叫m!
,那就會直接列印1
。
如果經過e!
的轉換,當然必當列印2
。
因此,答案是21
。
本作品採用《CC 協議》,轉載必須註明作者和本文連結