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个这样的东西,这样我就可以从变量中提取类型.然后, struct 可以如下所示:

#![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相关问答推荐

如何从Rust记录WASM堆内存使用情况?

如何在原始字符串中转义";#和#";

为什么复印是豆荚的一个重要特征?

如何为utoipa中的可选查询参数生成OpenAPI模式?

具有对同一类型的另一个实例的可变引用的

编译项目期间使用Cargo生成时出现rustc错误

如何为 struct 字段设置新值并在Ruust中的可变方法中返回旧值

正则表达式中的重叠匹配?(铁 rust 正则式发动机)

不能在一个代码分支中具有不变的自身borrow ,而在另一个代码分支中具有可变的self borrow

从未排序的链表中删除重复项的铁 rust 代码在ELSE分支的低级上做了什么?

JSON5中的变量类型(serde)

Rust中WPARAM和VIRTUAL_KEY的比较

Rust 中什么时候可以返回函数生成的字符串切片&str?

处理带有panic 的 Err 时,匹配臂具有不兼容的类型

将引用移动到线程中

如何在 Rust 中显式声明 std::str::Matches<'a, P> ?

为什么 no_std crate 可以依赖于使用 std 的 crate?

如何获取包裹在 Arc<> 和 RwLock<> 中的 Rust HashMap<> 的长度?

如何存储返回 Future 的闭包列表并在 Rust 中的线程之间共享它?

您如何使用枚举反序列化字符串,其中任何其他值反序列化为新类型变体同时保留字符串?