macros - 如何在隐式导出宏时使用模块中定义的构造

标签 macros rust

正在尝试从模块导出宏。宏生成实现模块中定义的一些特征的结构。有没有办法在不手动导入特征的情况下获得宏?

// src/lib.rs
#![crate_name="macro_test"]
#![crate_type="lib"]
#![crate_type="rlib"]

pub trait B<T> where T: Copy {
    fn new(x: T) -> Self;
}

#[macro_export]
macro_rules! test {
    ( $n:ident ) => {
        struct $n<T> where T: Copy {
            x: T
        }

        impl<T> B<T> for $n<T> where T: Copy {
            fn new(x: T) -> Self {
                $n { x: x }
            }
        }
    } 
}

// tests/test_simple.rs
#[macro_use]
extern crate macro_test;

test!(Test);

#[test]
fn test_macro() {
    let a = Test::<i32>::new(1);
}

在那种情况下我得到一个错误:

<macro_test macros>:2:54: 2:61 error: use of undeclared trait name `B` [E0405]
<macro_test macros>:2 struct $ n < T > where T : Copy { x : T } impl < T > B < T > for $ n < T >

如果我用 $crate 变量重写 trait 实现:

impl<T> $crate::B<T> for $n<T> where T: Copy {

错误信息更改为下一个:

tests\test_simple.rs:8:13: 8:29 error: no associated item named `new` found for type `Test<i32>` in the current scope
tests\test_simple.rs:8     let a = Test::<i32>::new(1);
                               ^~~~~~~~~~~~~~~~
tests\test_simple.rs:8:13: 8:29 help: items from traits can only be used if the trait is in scope; the following trait is implemented but not in scope, perhaps add a `use` for it:
tests\test_simple.rs:8:13: 8:29 help: candidate #1: use `macro_test::B`

为什么会这样?

最佳答案

因为如果不使用特征就不能调用特征方法。这与宏无关——这只是 Rust 中的标准规则。

也许您希望宏生成一个固有的 impl?

impl<T> $n<T> where T: Copy {
    pub fn new(x: T) -> Self {
        $n { x: x }
    }
}

而不是你现在拥有的。

关于macros - 如何在隐式导出宏时使用模块中定义的构造,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32941667/

相关文章:

c - 为什么这个使用移位的交换宏不适用于负数?

rust - 在迭代器特征中指定关联类型的生命周期

rust - RegOpenKeyEx 不断返回无效参数

c - 使用另一个宏生成#ifdef、#endif 子句

使用宏在两个函数定义之间进行更改

vim - 如何停止运行 Vim 宏

multithreading - 为什么这些线程在完成工作之前退出?

module - 在 Rust 中的模块内部使用模块

android - 为移动应用程序集成 Rust + Flutter + Kotlin

c - 迭代结构成员的宏