BT

InfoQ ホームページ ニュース メタプログラミングのサポートとモジュールが改善されたRust 1.30

メタプログラミングのサポートとモジュールが改善されたRust 1.30

ブックマーク

原文(投稿日:2018/11/02)へのリンク

Rustの最新リリースであるバージョン1.30では、プロシージャマクロが拡張され、新しい属性や関数風のマクロが定義可能になった。また、合理化と簡素化により、Rustモジュールシステムの効率が向上している。

Rust 1.30では、“属性型手続き型マクロ(attribute-like procedural macros)”と“関数型手続き型マクロ(function-like procedural macros)”という、2つのタイプの手続き型マクロが新たに導入されている。手続き型マクロはRustメタプログラミングの基礎であり、プログラム構文ツリーの操作を可能にする。この点において、手続き型マクロは宣言型マクロよりはるかに強力で、パターンマッチングに基づいた、より複雑なコードの省略形を定義するメカニズムを提供する。

属性型手続き型マクロは、既存の派生マクロ(derive macros)に近いが、新たに属性を定義できるという点でより柔軟であり、構造体や列挙型に加えて関数にも適用することができる。例として、属性型マクロを使用することで、HTTPルーティングを定義するroute属性が指定可能になる。

// use of route procedural macro
#[route(GET, "/")]
fn index() {
 ...
}

// procedural macro defining route
#[proc_macro_attribute]
pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
  // attr receives the GET, "/" part of the macro
  // item receives fn index () { ...
}

同じように、関数型手続き型マクロでは、関数のような外観のマクロを定義することができる。例えば、

// parse an SQL statement
let sql = sql!(SELECT * FROM posts WHERE id=1);

#[proc_macro]
pub fn sql(input: TokenStream) -> TokenStream {

いずれの例でも、TokenStreamは、属性が適用される構文ツリーあるいは属性/関数定義を表している。route/sql関数は、受信した構文ツリーを新たな構文ツリーに変換した上で呼び出し元に返す。すなわち、新たな実行コードを生成することができる。

Rust 1.30ではまた、useマクロが一部変更されたことにより、Rustモジュールシステムの開発者エクスペリエンスが向上している。最初に、useをマクロ定義で使用できるようになった。これに伴ってmacro_userアノテーションは廃止される。

// old:
#[macro_use]
extern crate serde_json;

// new:
extern crate serde_json;
use serde_json::json;

また、外部クレートのレジリエンシが向上しており、すべてのextern crateディレクティブに対して、モジュールプレリュードを含むすべての名前空間への参照がチェックされ、一致するものがあればそれを用いるようになった。これにより、モジュール階層全体を対象として機能するようになる。これまでは、モジュール内部でexternを明示的に使用するか、あるいは以下の例に示すような::extern_name構文を使用する必要があった。

extern crate serde_json;

fn main() {
    let json = serde_json::from_str("..."); // OK
}

mod foo {

    // to use serde_json in this module you explicitly use it
    use serde_json;

    fn bar() {
        let json = serde_json::from_str("...");
    }

    fn baz() {
      // alternatively, you fully qualify the external module name
      let json = ::serde_json::from_str("...");
    }

最後に、useでモジュールパスを解釈する方法の一貫性が向上した。crateキーワードを使って、crateルートの開始点としたいモジュールパスを指定することが可能になった。1.30より前はこれがモジュールパスの既定値だったが、アイテムを直接参照するパスはローカルパスから開始される。

mod foo {
    pub fn bar() {
        // ...
    }
}

mod baz {
    pub fn qux() {
    
        // old
        ::foo::bar();
        // does not work, which is different than with `use`:
        // foo::bar();

        // new
        crate::foo::bar();
    }
}

その他にもRust 1.30では、次のような点が変更されている。

  • r#forのようにr#を先頭に付けることで、キーワードを識別子として使用できるようになった。この変更は主に、Rust 2018で新たなキーワードが導入されるという事実に基づくもので、新たなキーワードを変数や関数名として使用している既存コードを変換する仕組みとして利用することができる。
  • no_stdを指定して、標準ライブラリを使用しないアプリケーションの構築が可能になった。これまでは、パニックハンドラを定義することができないため、no_stdでライブラリを構築することのみが可能であった。

Rustディストリビューションの更新は、$ rustup update stableを使って行うことができる。 Rust 1.30の詳細はリリースノートで確認してほしい。

 
 

この記事を評価

採用ステージ
スタイル
 
 

この記事に星をつける

おすすめ度
スタイル

特集コンテンツ一覧

.NETエコシステムの紹介

David Pine 2019年11月7日 午後7時48分

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

コミュニティコメント

  • タイポ

    by Mikhailov Eugene /

    スパムの可能性があると認識されました。モデレーターが確認し問題がなければ24時間以内に公開します。その際あなたへの通知は行われませんのでご了承ください。

    macro_userアノテーションは廃止

    macro_useアノテーションは廃止
    ではないでしょうか。

  • タイポ

    by Mikhailov Eugene /

    スパムの可能性があると認識されました。モデレーターが確認し問題がなければ24時間以内に公開します。その際あなたへの通知は行われませんのでご了承ください。

    macro_userアノテーションは廃止

    macro_useアノテーションは廃止
    ではないでしょうか。

  • タイポ

    by Mikhailov Eugene /

    スパムの可能性があると認識されました。モデレーターが確認し問題がなければ24時間以内に公開します。その際あなたへの通知は行われませんのでご了承ください。

    macro_userアノテーションは廃止

    macro_useアノテーションは廃止
    ではないでしょうか。

  • Re: タイポ

    by Mikhailov Eugene /

    スパムの可能性があると認識されました。モデレーターが確認し問題がなければ24時間以内に公開します。その際あなたへの通知は行われませんのでご了承ください。

    すみません,操作がうまくいかなかったので何度もやったら複数回ポストされてしまいました。削除お願いします。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

BT

あなたのプロファイルは最新ですか?プロフィールを確認してアップデートしてください。

Eメールを変更すると確認のメールが配信されます。

会社名:
役職:
組織規模:
国:
都道府県:
新しいメールアドレスに確認用のメールを送信します。このポップアップ画面は自動的に閉じられます。