在 macro_rules 中存储状态

莱斯普

我想创建一个对给定类型列表进行操作的宏,但我需要能够存储正在处理的其他类型。

我想做的事情的一个简单示例:

struct Foo;

struct Bar {
   foo: Foo,
   data: u32,
}

baz!(Foo, Bar);

// outputs
struct OptFoo;

struct OptBar {
   foo: OptFoo,
   data: u32
}

问题是它似乎macro_rules不允许我存储临时状态(即HashSet我将标记哪些类型是宏调用的一部分)。我想到的唯一解决方法是编写我想要的内容proc_macro_derive并为我需要的每种类型手动添加自定义属性,但这显然远非完美......

编辑:

问题与问题类似,但在这里我尝试在单个宏调用中本地和临时保存状态(基本上是在存储有关参数的数据时对参数进行两次传递)。然而,这似乎也是不可能的。

莱斯普

正如@trentcl 所指出的,我想要实现的目标确实可以通过 proc 宏实现(我认为 proc 宏仅限于Derive和属性......)

#[proc_macro]
pub fn generate(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
    let input = proc_macro2::TokenStream::from(input);

    println!("{:?}", input);

    proc_macro::TokenStream::from(input)
}

generate!(struct Foo;);

// outputs its argument without changing anything, i.e:
// struct Foo ;

前面的例子演示了一个简单的宏,它打印到 sdout 解析的输入: TokenStream [Ident { ident: "struct", span: #0 bytes(330..336) }, Ident { ident: "Foo", span: #0 bytes(337..340) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(340..341) }]

请注意,它解析令牌但不创建 AST;我们将不得不使用syn它。

这个 repo有很多例子可以用 proc 宏完成,非常有帮助!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章