如何在外部使用宏的内部结构?

How to use macro's internal struct outside?

我想知道如何构造一个定义在宏中的结构。测试代码如下:Play Ground Test

fn main() {
    #[macro_export]
    macro_rules! helper {
        ($a: expr) => {{
            #[derive(Debug)]
            struct Person {
                pub age: u64,
            }

            let p = Person { age: $a };
            p
        }};
    }

    let x = helper!(5);
    println!("The struct get in main.rs {:?}", x);

    let p = Person { age: 3 };
}

错误消息:

error[E0422]: cannot find struct, variant or union type `Person` in this scope
  --> src/main.rs:19:13
   |
19 |     let p = Person { age: 3 };
   |             ^^^^^^ not found in this scope

error: aborting due to previous error

For more information about this error, try `rustc --explain E0422`.

但是还有另一个例子可以正常工作。我想知道这里发生了什么。

fn main() {
    #[macro_export]
    macro_rules! r {
        () => {
            #[derive(Debug)]
            struct A;
            impl A {
                fn new() -> Self { A }
            }
        };
    }

    pub mod m {
        pub use crate::r;
    }
    
    m::r! {}
    
    dbg!(A{});
}

您不能简单地使用一个表达式来声明外部作用域的结构。

我会将您的宏更改为不是 return 表达式,而是创建结构和执行赋值:

fn main() {
    #[macro_export]
    macro_rules! helper {
        ($var:ident, $a: expr) => {
            #[derive(Debug)]
            struct Person {
                pub age: u64,
            }
            let $var = Person { age: $a };
        };
    }

    helper!(x, 5);
    println!("The struct get in main.rs {:?}", x);

    let p = Person { age: 3 };
}