1. ホーム
  2. module

[解決済み] モジュールファイルをまたいでマクロを使用するには?

2022-05-24 22:03:43

質問

同じクレート内の別々のファイルに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' マクロシステムはモジュールシステムの前に実行されるので、これは理にかなっています。どのように私はそれを回避するのですか?

どのように解決するのですか?

同一クレート内のマクロ

新しいメソッド (Rust 1.32, 2019-01-17 以降)

foo::bar!();  // works

mod foo {
    macro_rules! bar {
        () => ()
    }

    pub(crate) use bar;    // <-- the trick
}

foo::bar!();  // works

を使うと pub use を使用すると、マクロは他の項目と同様に使用およびインポートできます。また、旧来の方法とは異なり、ソースコードの順序に依存しないため、マクロが定義される前 (ソースコードの順序) に使用することができます。

古い方法

bar!();   // Does not work! Relies on source code order!

#[macro_use]
mod foo {
    macro_rules! bar {
        () => ()
    }
}

bar!();    // works

同じクレートでマクロを使用したい場合、マクロが定義されているモジュールには、属性 #[macro_use] . なお、マクロは の後に の後にしか使えません。




クレートをまたぐマクロ

木枠 util

#[macro_export]
macro_rules! foo {
    () => ()
}

木枠 user

use util::foo;

foo!();

この方法では、マクロは常に木箱のトップレベルに存在することに注意してください! ですから、たとえ foo の中にあったとしても mod bar {} の中にあり、その user クレートはまだ use util::foo; ではなく use util::bar::foo; . を使うことで pub use を使うことで、(ルートでエクスポートされるのに加えて) 木箱のモジュールからマクロをエクスポートすることができます。

Rust 2018以前は、他のクレートからマクロをインポートするには、属性に #[macro_use] を追加していました。 extern crate util; ステートメントに追加します。そうすると、すべてのマクロが util . この構文はもう必要ないはずです。