來自於RustFest 2018 大會上Alex Crichton 和 David Tolnay兩位大佬的輕演講主題:Rust Quiz

rust-quiz源碼在線練習和解答

視頻

不得不說,兩位大佬出的題非常具有迷惑性,一不留神就落入了陷阱。

Quiz 22:

下面這段代碼輸出什麼?

macro_rules! m {
($a:tt) => { print!("1") };
($a:tt $b:tt) => { print!("2") };
($a:tt $b:tt $c:tt) => { print!("3") };
($a:tt $b:tt $c:tt $d:tt) => { print!("4") };
($a:tt $b:tt $c:tt $d:tt $e:tt) => { print!("5") };
($a:tt $b:tt $c:tt $d:tt $e:tt $f:tt) => { print!("6") };
($a:tt $b:tt $c:tt $d:tt $e:tt $f:tt $g:tt) => { print!("7") };
}

fn main() {
m!(-1);
m!(-1.);
m!(-1.0);
m!(-1.0e1);
m!(-1.0e-1);
}

輸出結果: 22222

考察要點:

  1. 聲明宏模式分支匹配規則
  2. Rust如何對表達式進行詞法分析

Quiz代碼中定義了m!宏,通過該宏可以判斷Rust如何對表達式進行解析。

在main函數中:

m!(-1),其中-1,會被Rust分詞為兩個獨立詞條(Token):-1。所以,宏調用會匹配到第二個模式條件分支,最終輸出:2

Rust對於數字11.1.01.0e11.0e-1均會識別為一個詞條。所以,剩餘的4個宏調用,也同樣會輸出: 2

-永遠都會被識別為獨立的詞條,比如下面這段代碼:

fn main() {
let n = -3i32.pow(4);
println!("{}", n);
}

輸出結果是:-81

點此查看 Rust Quiz 22

推薦閱讀:

相關文章