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

标签 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! 宏,如果我用 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/

相关文章:

rust - 你如何在 Rust 中实现这个简单的 trie 节点?

rust - 为什么这个结构成员需要两个生命周期?

performance - 优化 rust N 素数生成器

rust - 可以避免在 'impl' 函数体中重复结构名称吗?

error-handling - 创建Rust错误填充程序的惯用方式是什么?

error-handling - Rust Arc/Mutex Try 宏借用的内容

rust - 在 T 和 UnsafeCell<T> 之间转换是否安全且已定义行为?

rust - 如何让调用者看到方法的特征实现?

rust - 如何使用 structopt 将特殊字符作为字符串参数传递?

json - JSON响应的反序列化在字符串中保留引号