具体来说,我正在尝试将宏输出放入文档注释中。我很兴奋这正是我想要的:
/// foo
///
#[doc="bar\n\nbaz"]
///
/// quux
struct Dummy;
下一步是用我的内容替换该字符串。据此,我不会写#[doc=my_content!()]
,并且属性宏是程序性的,所以我需要另一个板条箱,而且(我认为)我的内容可以在不需要任何程序性宏功能的情况下生成。
有没有办法以某种方式使用“常规宏”来做到这一点,还是我不走运?
具体来说,我正在尝试将宏输出放入文档注释中。我很兴奋这正是我想要的:
/// foo
///
#[doc="bar\n\nbaz"]
///
/// quux
struct Dummy;
下一步是用我的内容替换该字符串。据此,我不会写#[doc=my_content!()]
,并且属性宏是程序性的,所以我需要另一个板条箱,而且(我认为)我的内容可以在不需要任何程序性宏功能的情况下生成。
有没有办法以某种方式使用“常规宏”来做到这一点,还是我不走运?
编辑:从 1.54.0 开始,属性可以调用类似函数的宏,从而启用问题中提出的代码。下面的原始答案:
答案似乎是否定的。
查看属性的语法,除了括号、逗号和等号,属性最终只能包含文字。所以在这个层面上,Rust 没有办法在这里允许更多。
然而,反转结构可以实现这样的功能,并且doc-comment
crate 为文档注释执行此操作。不要从属性内部调用宏,而是使用宏来创建属性;然后,该宏不限于仅采用文字*。缺点是,该属性应该应用到的项目必须是宏调用的一部分。所以这
#[doc=my_content!()]
struct Foo;
变成这样:
doc_comment!(
my_content!(),
struct Foo;
);
宏的定义很简单:
#[macro_export]
macro_rules! doc_comment {
($x:expr, $($tt:tt)*) => {
#[doc = $x]
$($tt)*
};
}
(省略了不属于核心模式的原始宏的一个分支)
(感谢 jonas-schlevink 向我指出这一点)
*除了最后一部分(将宏内容放入属性中),链接问题的答案已经完全做到了。