我正在建立一个具有foo
功能的板条箱。这个板条箱有一个宏bar!
,它根据是否设置了foo
来做一些细微的事情。
我可以复制整个宏:
#[cfg(feature = "foo")]
macro_rules! bar {
// Lots of rules...
( A ) => {
B
}
}
#[cfg(not(feature = "foo"))]
macro_rules! bar {
// Lots of rules...
( A ) => {
C
}
}
这是很多容易出错的重复。两种无效的方法:
我们无法在宏内移动cfg
,因为这样它将在板条箱用户的范围内扩展,该范围没有适当设置功能foo
。
从Rust 1.30开始,我们不能使用#[doc(hidden)] #[macro_export] macro_rules! bar_priv_impl__
帮助宏,而不能在辅助宏上使用#[cfg]
,因为用户现在可以请求use mycrate::bar;
只导入{{ 1}}宏,给出有关如何定义bar!
的错误。
有什么方法比完整的宏复制更好吗?如果您要测试的N个功能真的很糟糕,因为您需要 2 n 个重复项。
答案 0 :(得分:2)
由于Rust 1.30 [...],因为用户现在只能导入
bar!
宏
实际上,该解决方案在Rust 1.30中仅 可行,因为它能够像普通的那样导入宏。请记住,您的宏还可以 具有use
条语句!:
#[macro_export]
macro_rules! bar {
($val:expr) => {{
use $crate::__bar_foo;
__bar_foo!($val)
}}
}
#[cfg(feature = "foo")]
#[macro_export]
macro_rules! __bar_foo {
($val:expr) => ($val + 1)
}
#[cfg(not(feature = "foo"))]
#[macro_export]
macro_rules! __bar_foo {
($val:expr) => ($val - 1)
}
您还可以完全限定助手宏的调用:
#[macro_export]
macro_rules! bar {
($val:expr) => ($crate::__bar_foo!($val))
}