目次

Rustの勉強[マクロ その3]

ぎじゅつ

はじめに

#

NO IMAGEマクロ - The Rust Programming Language 日本語版

を読んでいる

お勉強

#

NO IMAGEマクロ - The Rust Programming Language 日本語版

  • derive?をやる

メモ

#

hello_macro関数の既定の実装を得られるように、手続き的マクロを提供します。

  • あ、これ手続き的なんやね
  • AIと壁打ちしてなんとなくnixでわかった
    • Derivationは手続き的
    • moduleを利用するときは宣言的(なことがおおい)
  • 戻りましょ
use hello_macro::HelloMacro;
use hello_macro_derive::HelloMacro;

#[derive(HelloMacro)]
struct Pancakes;

fn main() {
    Pancakes::hello_macro();
}
  • これを書けるようにしたい
pub trait HelloMacro {
    fn hello_macro();
}
use hello_macro::HelloMacro;

struct Pancakes;

impl HelloMacro for Pancakes {
    fn hello_macro() {
        println!("Hello, Macro! My name is Pancakes!");
    }
}

fn main() {
    Pancakes::hello_macro();
}
  • この辺を定義する
  • まあ分かるか

しかしながら、使用者は、hello_macroを使用したい型それぞれに実装ブロックを記述する必要があります; この作業をしなくても済むようにしたいです。

  • 繰り返しだしなー

Rustにはリフレクションの能力がないので、型の名前を実行時に検索することができないのです。コンパイル時にコード生成するマクロが必要です。

  • Rustってリフレクションないのか

fooというクレートに対して、カスタムのderive手続き的マクロクレートはfoo_deriveと呼ばれます。

  • あーderiveっていうマクロかと思ったけど機能の名称なんだ
  • hello_macroにこれが必要らしい
extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn;

#[proc_macro_derive(HelloMacro)]
pub fn hello_macro_derive(input: TokenStream) -> TokenStream {
    // 操作可能な構文木としてのRustコードの表現を構築する
    // Construct a representation of Rust code as a syntax tree
    // that we can manipulate
    let ast = syn::parse(input).unwrap();

    // トレイトの実装内容を構築
    // Build the trait implementation
    impl_hello_macro(&ast)
}
  • 終わってるぐらいわからない

まとめ

#
  • 最後まったく分からなかった
  • あんまりダラダラやりたくないなー
  • 次はここから
    • TokenStreamをパースする役割をもつ