我有相同宏的不同版本,我希望能够在编译时选择其中一个。
这是我的代码:
macro_rules! macro_a {
($identifier:ident) => {
println!("A: {}", stringify!($identifier));
}
}
macro_rules! macro_b {
($identifier:ident) => {
println!("B: {}", stringify!($identifier));
}
}
macro_rules! macro_c {
($identifier:ident) => {
println!("C: {}", stringify!($identifier));
}
}
macro_rules! choose_macro {
(a) => {
const CHOSEN_MACRO: u32 = 1;
};
(b) => {
const CHOSEN_MACRO: u32 = 2;
};
(c) => {
const CHOSEN_MACRO: u32 = 3;
};
}
choose_macro!(c);
macro_rules! use_macro {
($identifier:ident) => {
match CHOSEN_MACRO {
1 => macro_a!($identifier),
2 => macro_b!($identifier),
3 => macro_c!($identifier),
_ => unreachable!(),
}
}
}
fn main() {
use_macro!(test);
}
这将按预期打印:
C: test
我想知道是否有更好的方法(使用宏或属性或其他任何东西)。
目前还不清楚是否在编译时选择了宏。 Will Rust会删除匹配,因为它是常量吗?
更新:我更喜欢在代码中选择宏,而不是使用编译器标志。另外,我不想隐藏未选择的宏:我希望能够使用它们的真实名称来使用它们。
答案 0 :(得分:2)
我建议使用条件编译标志来做这样的事情。见https://doc.rust-lang.org/book/conditional-compilation.html
在您的情况下,它可能看起来像这样:
#[cfg(feature = "feature_a")]
macro_rules! use_macro {
($identifier:ident) => {
println!("A: {}", stringify!($identifier));
}
}
#[cfg(feature = "feature_b")]
macro_rules! use_macro {
($identifier:ident) => {
println!("B: {}", stringify!($identifier));
}
}
#[cfg(feature = "feature_c")]
macro_rules! use_macro {
($identifier:ident) => {
println!("C: {}", stringify!($identifier));
}
}
fn main() {
use_macro!(test);
}
然后将以下内容添加到您的Cargo.toml文件中:
[features]
feature_a = []
feature_b = []
feature_c = []
如果你想要打印出来" C:test"例如,然后运行以下命令:
cargo run --features feature_c