是否可以在 Rust 的过程宏中存储​​状态?

Posted

技术标签:

【中文标题】是否可以在 Rust 的过程宏中存储​​状态?【英文标题】:Is it possible to store state within Rust's procedural macros? 【发布时间】:2019-03-25 10:23:21 【问题描述】:

是否可以构建一个不输出任何内容但存储状态以构建列表的宏,然后再构建一个实际使用该数据的宏?

例如:

trait SomeTrait 

#[derive(mark)]
struct Person 

impl SomeTrait for Person 

#[derive(mark)]
struct Item 

impl SomeTrait for Item  

#[derive(mark)]
struct Object 

impl SomeTrait for Object 

create_mapper! // this then outputs the below function
//assuming for the fact that data is loaded correctly before this macro is used

fn select_item(kind: String) -> impl SomeTrait 
    match kind 
        "person" => Person,
        "item" => Item,
        "object" => Object,        
    

【问题讨论】:

请说的更具体些,要存什么货?你想怎么用?明确地说,程序宏可以做的不仅仅是宏,但不是魔术,存储状态需要将其存储在某个地方,静态,常量,其他东西。 您可能指的是match,而不是您要生成的代码中的map。您还需要添加一个包罗万象的分支。 关于您的实际问题,我会保持明确并使用类型定义 enum。您可以定义一个简单的声明性宏来减少样板。 【参考方案1】:

目前没有官方支持的存储状态的方式可以被两个不同的 proc 宏调用使用。我在讨论这个问题的地方创建了this very related issue。

存储状态当然是可能的,但只是以一种 hacky 的方式。例如,您可以将所有状态序列化为/tmp/my-state。或者您可以尝试使用static 全局变量。但是,即使现在可以使用,也不能保证将来可以使用。另一个问题:由于增量编译,不能保证所有 proc 宏调用都实际执行。因此,如果您有一个生成状态的宏和一个读取状态的宏,如果第一个没有执行,就会发生非常奇怪的事情。所以存储全局状态在技术上是可行的,但不建议这样做。

在上面链接的问题中,您可以看到 MSleepyPanda proposed a possible solution,但我们远未实现。

【讨论】:

啊,是的,我确实看到了这个问题,但我认为有人可能已经提出了解决方案。

以上是关于是否可以在 Rust 的过程宏中存储​​状态?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以忽略 Rust 的指数?

在过程宏中,如何检查字符串是不是是有效的变量名而不是关键字?

Rust 声明性宏中的 @ 符号是啥意思?

如何在Rust宏中使用ty

如何在宏中匹配 Rust 的“if”表达式?

如何在过程宏中提供有用的编译器错误?