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

时间:2014-08-09 11:18:57

标签: 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();
}

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

这可能吗?我认为这里最大的问题是我需要来自C ++的decltype之类的内容,以便我可以从变量中提取类型。结构可能看起来像:

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

1 个答案:

答案 0 :(得分:10)

不,只有表达式标识符才能做到这一点。您需要显式类型,例如

macro_rules! make_printer {
    ($($element: ident: $ty: ty),*) => {
        struct Foo { $($element: $ty),* }
    }
}

调用make_printer!(x: i32, y: String)

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

  • 宏不能访问任何类型信息,它们只是本地语法转换(例如,它甚至不可能编写宏(macro_rules!或程序),可以判断给定ident指的是局部变量。)
  • Rust没有decltype等价物。