2016-10-28 2 views
10

私はRustに関する本を読んでおり、Rust macrosで遊んでいます。すべてのメタ変数型がここに説明されており、最後のものを除いて例があります - tt。本によると、それは「単一のトークンツリー」です。私は興味があります、それは何ですか?それは何のために使用されていますか?あなたは例を挙げていただけますか?Rustマクロでは、ttメタバリアブル型の意味は何ですか?

答えて

14

これは、マクロ呼び出しにあるものが(),[]{}のペアと正しく一致するように導入された概念です。

例えば、以下のプログラムのために:

fn main() { 
    println!("Hello world!"); 
} 

トークンツリーは次のようになります

  • fn
  • main
  • ()
  • { println!("Hello world!"); }
    • println
    • !
    • ("Hello world!")
      • "Hello world!"
    • ;

これは、単純なトークン(fnmainなど)ツリーを形成葉であり、()[]または{}に囲まれたものは、サブツリーを持っています。 (はトークンツリーに単独では表示されません。対応する)と一致しないで(と一致することはできません。例えば

macro_rules! { 
    (fn $name:ident $params:tt $body:tt) => { /* … */} 
} 

$name → main$params →()$body → { println!("Hello world!"); }と上記関数にマッチします。

トークンツリーは、最も要求の厳しいメタ変数タイプです。これは何でも一致します。これは、 "本当に気にしない"部分、特に "頭"と "尾"部分を持つマクロでよく使われます。たとえば、println!マクロは、$fmtがフォーマット文字列である($fmt:expr, $($arg:tt)*)と一致するブランチを持ち、$($arg:tt)*は「すべての残り」を意味し、ちょうどformat_args!に転送されます。つまり、println!は実際のフォーマットを知る必要はなく、複雑なマッチングを行う必要はありません。

+0

良い説明と例をお寄せいただきありがとうございます。 –