rust - 在 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 宏完成的例子,非常有帮助!
推荐阅读
- java - 使用 Jframe 检查句子是否为 pangram
- visual-studio-code - 使用 webpack 时如何在 VSCode 扩展中的 TreeItem 上使用图标
- python-3.x - 我应该添加什么来删除这个 imagedatabunch 错误 NameError: name 'ImageDataBunch' is not defined
- laravel-8 - 将变量从路由传递给控制器方法
- angularjs - 基于另一个字段值的条件渲染标签颜色
- reactjs - Oidc 授权 redux-react 重定向问题
- android - 如何在 HighCharts Android 包装器中仅将borderRadius应用于柱形图的顶部
- laravel - 方法 Illuminate\Auth\SessionGuard::personnel 不存在
- javascript - 如何在 Visual Studio 中编码此 api 请求的结果
- html - 在 React 中用 img 填充 div