我正在创建一个 attribute macro可以通过其属性中的某种类型(路径)调用:
#[my_macro(path::to::SomeType)]
这个宏生成一个模块,其中指定的类型将被使用:
mod generated {
use path::to::SomeType;
}
但是,从生成的模块中,提供的路径可能不再正确:
- 如果路径以
::
为前缀,它仍然是正确的——我可以在 proc 宏中确定这一点; - 否则,如果路径以前奏中的标识符开始(例如外部包装箱的标识符),它仍然是正确的——我看不出有任何方法可以在 proc 宏中确定这一点;
- 否则它现在必须以
super::
为前缀才能成功解析。
当然,我可以要求宏的用户在生成的模块中提供一个正确的路径,但这不太符合人体工程学。
相反,我目前正在父模块中生成一个类型别名:
type __generated_SomeType = path::to::SomeType;
mod generated {
use super::__generated_SomeType as SomeType;
}
但这不仅有点笨拙,而且还会污染父命名空间。
有没有更好的办法?
最佳答案
我认为没有令人满意的解决方案。但还有一种替代方法,可以改进您当前的方法。
另一种方法是使用 const
项:
const _: () = {
// ... your generated code here
};
它仍然会导致与父作用域中的项目发生名称冲突,但至少生成的项目在 const
之外是不可见的。这是大多数宏作者所做的。
如果你不想这样做,你可以使用你当前的方法,但是你应该添加 #[doc(hidden)]
到 __generated_SomeType
类型,因此它不会出现在文档中。此外,您应该使用导入而不是类型别名来支持泛型类型,正如@ChayimFriedman 所建议的那样:
#[doc(hidden)]
use path::to::SomeType as __generated_SomeType;
我正要建议通过将模块放入 const
项目中来将这些方法结合起来,但它不起作用:
const _: () = {
use path::to::SomeType as __generated_SomeType;
mod generated {
// doesn't work :(
use super::__generated_SomeType as SomeType;
}
};
Rust 提示 __generated_SomeType
在父模块中不存在。
关于rust - 在给定父模块上下文中的路径的子模块上下文中生成路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71849696/