module - 如何跨模块文件使用宏?

标签 module rust rust-macros

我在同一个 crate 中的不同文件中有两个模块,其中 crate 启用了 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'”...这是有道理的;宏系统在模块系统之前运行。我该如何解决这个问题?

最佳答案

同一个 crate 中的宏

新方法(自 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

如果你想在同一个 crate 中使用宏,定义你的宏的模块需要属性 #[macro_use]。请注意,宏只能定义后使用!



跨 crate 的宏

Crate util

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

创建用户

use util::foo;

foo!();

请注意,使用此方法,宏始终位于 crate 的顶层!因此,即使 foo 位于 mod bar {} 内,user crate 仍然必须编写 use util::foo ; 并且 使用 util::bar::foo;。通过使用 pub use,您可以从 crate 的模块中导出宏(除了在根目录中导出宏之外)。

在 Rust 2018 之前,您必须通过将属性 #[macro_use] 添加到 extern crate util; 语句来从其他 crate 导入宏。这将从 util 导入所有宏。不再需要此语法。

关于module - 如何跨模块文件使用宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51637870/

相关文章:

rust - ListNode的下一个字段类型为Option<Box<ListNode>>,是否正确?

rust - 我怎样才能拥有一个仅用于其内部常量的结构?

rust - 编写一个函数来获取引用和值类型的迭代

rust - 实现 proc 宏时的循环包依赖

Javascript 模块模式 : When to go private with methods? Getters/setters?改进空间?

virtualenv : broken `site.py` 下的 Python 2.7

python - Tornado WebSocket 问题

rust - 我可以使用 Rust 的宏重复检测表达式是否为可变变量吗?

rust - 理解 Rust `tt` 宏中的 `macro_rules!`

haskell - 导入 Haskell 模块特定部分的好处