web-dev-qa-db-ja.com

モジュールファイル間でマクロを使用するにはどうすればよいですか?

同じクレート内の別々のファイルに2つのモジュールがあり、クレートにはmacro_rules有効。あるモジュールで定義されているマクロを別のモジュールで使用したい。

// macros.rs
#[macro_export] // or not? is ineffectual for this, afaik
macro_rules! my_macro(...)

// something.rs
use macros;
// use macros::my_macro; <-- unresolved import (for obvious reasons)
my_macro!() // <-- how?

現在、コンパイラエラー "macro undefined: 'my_macro' "...これは理にかなっています。マクロシステムはモジュールシステムの前に実行されます。どうすれば回避できますか?

50
user

Rust 1.1.0-stable。


#![macro_escape]の先頭にmacros.rsを追加し、 マクロガイド で説明されているようにmod macros;を使用して含める必要があります。

$ cat macros.rs
#![macro_escape]

#[macro_export]
macro_rules! my_macro {
    () => { println!("hi"); }
}

$ cat something.rs
#![feature(macro_rules)]
mod macros;

fn main() {
    my_macro!();
}

$ rustc something.rs
$ ./something
hi

将来の参考のために、

$ rustc -v
rustc 0.13.0-dev (2790505c1 2014-11-03 14:17:26 +0000)
15
Dogbert

マクロを含むファイルの先頭に#![macro_use]を追加すると、すべてのマクロがmain.rsにプルされます。

たとえば、このファイルの名前がnode.rsであると仮定します。

#![macro_use]

macro_rules! test {
    () => { println!("Nuts"); }
}

macro_rules! best {
    () => { println!("Run"); }
}

pub fn fun_times() {
    println!("Is it really?");
}

Main.rsはいつか次のようになります。

mod node;  //We're using node.rs
mod toad;  //Also using toad.rs

fn main() {
    test!();
    best!();
    toad::a_thing();
}

最後に、これらのマクロも必要とするtoad.rsというファイルがあるとします。

use node; //Notice this is 'use' not 'mod'

pub fn a_thing() {
  test!();

  node::fun_times();
}

modを使用してファイルがmain.rsに取り込まれると、残りのファイルはuseキーワードを介してファイルにアクセスできることに注意してください。

1
Luke Dupin