将状态存储在 macro_rules
Store state in 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
。
This repo 有许多可以使用 proc 宏完成的示例,非常有帮助!
我想创建一个对给定类型列表进行操作的宏,但我需要能够存储正在处理的其他类型。
我想做的事情的一个简单例子:
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
。
This repo 有许多可以使用 proc 宏完成的示例,非常有帮助!