是否可以使用宏生成结构?

Mai*_*ein 5 rust

trait Print {
    fn print(&self);
}
struct Printer {
    p: Box<Print>,
}
fn main() {
    let i = 1i32;
    let s = String::from_str("Hello");

    // let mp = make_printer!(i,s);
    let mp = |i: i32, s: String| {
        struct Foo {
            i: i32,
            s: String,
        }
        impl Foo {
            fn new(i: i32, s: String) -> Foo {
                Foo { i: i, s: s }
            }
        }
        impl Print for Foo {
            fn print(&self) {
                println!("{} {}", self.i, self.s);
            }
        }
        Printer { p: box Foo::new(i, s) }
    };

    let printer = mp(i, s);
    printer.p.print();
}
Run Code Online (Sandbox Code Playgroud)

我想创建一个make_printer!宏,mp如果我调用它,它应该扩展到make_printer!(i,s).

这有可能吗?我认为这里最大的问题是我需要像decltypeC++这样的东西,以便我可以从变量中提取类型.该结构可能看起来像:

#![feature(macro_rules)]
macro_rules! make_printer(
    ($($element:ident),*) => (
        struct Foo{
            $($element : decltype($element),)*
        }
    )
)
Run Code Online (Sandbox Code Playgroud)

huo*_*uon 10

不,只有表达式标识符才能做到这一点.你需要明确的类型,例如

macro_rules! make_printer {
    ($($element: ident: $ty: ty),*) => {
        struct Foo { $($element: $ty),* }
    }
}
Run Code Online (Sandbox Code Playgroud)

叫起来像make_printer!(x: i32, y: String).

这是两个,主要是正交的原因所必需的:

  • 宏不能访问任何类型信息,它们只是局部语法转换(例如,它甚至不可能编写一个宏(无论是macro_rules!程序还是程序),它可以判断给定是否ident引用了局部变量).
  • Rust没有decltype相应的东西.