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!
宏,如果我用 make_printer!(i,s)
调用它,它应该扩展为 mp
。
这可能吗?我认为这里最大的问题是我需要 C++ 中的 decltype
之类的东西,以便我可以从变量中提取类型。该结构可能如下所示:
#![feature(macro_rules)]
macro_rules! make_printer(
($($element:ident),*) => (
struct Foo{
$($element : decltype($element),)*
}
)
)
最佳答案
不,仅使用表达式标识符是不可能的。您需要显式类型,例如
macro_rules! make_printer {
($($element: ident: $ty: ty),*) => {
struct Foo { $($element: $ty),* }
}
}
像 make_printer!(x: i32, y: String)
一样调用。
出于两个主要是正交的原因,这是必需的:
- 宏无法访问任何类型信息,它们只是局部句法转换(例如,甚至不可能编写一个宏(
macro_rules!
或过程)来判断给定的是否为ident
指的是局部变量)。 - Rust 没有
decltype
等价物。
关于rust - 是否可以使用宏生成结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25217988/