如何在Rust中导入宏?

22

我在如何从外部crate导入宏方面遇到了困难。在我的main.rs中,我正在导入Glium crate:

#![macro_use]
extern crate glium;

pub use glium::*;

// where my actual main function will be done from
mod part01drawtriangle;

fn main() {
    part01drawtriangle::main();
}

在我的另一个文件中,我的主函数来自那里,我调用了该箱的一个宏:

pub fn main() {
    implement_vertex!(Vertex, position);
}

在构建时,我收到以下错误信息:

error: macro undefined: 'implement_vertex!'

我遇到了同样的问题,也是在使用glium时,但尝试应用下面的解决方案并不起作用。我一直收到宏未定义的错误。我的目录结构是[main.rs,lib.rs,tutorial:[mod.rs,draw_triangle.rs]],其中implement_vertex!被用于draw_triangle.rs。 - jz87
3个回答

23

#[macro_use],而不是#![macro_use]

#[..]将属性应用于其后的事物(在本例中为extern crate)。#![..]将属性应用于包含的事物(在本例中为根模块)。


但是我遇到了这样的错误:failed to resolve. Use of undeclared type or module glium::glutin::WindowBuilder。这是命名空间相关的吗?我已经添加了use glium::*;`,但仍然不起作用。 - Adityo Pratomo
听起来像是一个脆弱的宏。尝试在 part01drawtriangle.rs 的顶部添加 use glium; - DK.
2
你可能想要在 crate 上开一个问题;解决方案是在宏定义中使用 $crate:: 而不是 glium:: - DK.

18
根据 Rust Edition Guide
在 Rust 2018 中,你可以通过 use 语句从外部包中导入特定的宏,而不是使用旧的 #[macro_use] 属性。
// in a `bar` crate's lib.rs:
#[macro_export]
macro_rules! baz {
    () => ()
}

// in your crate:
use bar::baz;

// Rather than:
//
// #[macro_use]
// extern crate bar;

这仅适用于在外部 crate 中定义的宏。对于本地定义的宏,仍需要使用 #[macro_use] mod foo;,就像在 Rust 2015 中一样。

4
截至2022年3月,macro_export导出到根目录,并且可以与'use crate::baz'一起使用的宏。 - franckspike

1
如果在同一项目中由库导出并由二进制文件导入的宏,则使用以下模式。
从 `lib.rs` 中,该文件是 `Cargo.toml` 中 `[lib]` 定义的一部分。
// src/lib/lib.rs

#[macro_export]
macro_rules! my_macro {
    // ...
}
pub use my_macro;

Cargo.toml 中的 [[bin]] 定义中的客户端文件 bin.rs

// src/bin/bin.rs

use crate::my_macro;

每个导入的宏都需要自己的单独use语句。不能与宏一起导入多个项目(这些需要单独的use语句)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接