在C ++中,您可以取消定义并重新定义宏。 例如,视频游戏中常见的事情是在发布模式下将日志记录宏重新定义为空。这可以保证代码完全消失,这有助于提高性能。
有没有办法在Rust中做类似的事情?
答案 0 :(得分:6)
基本上你可能会这样做:
macro_rules! log_if_dbg {
(...) => (if cfg!(debug_assertions) { /* do logging */ })
}
这就是the macro debug_assert!
的实施方式。医生说:
与assert!,debug_assert不同!语句仅在非中启用 默认情况下优化构建。优化的构建将省略所有 debug_assert!语句,除非-C debug-assertions传递给 编译器。这使得debug_assert!对于支票也很有用 在发布版本中存在昂贵但在此期间可能会有所帮助 发展。
这与您的情况相同,仅用于断言,而不是记录。查看source:
macro_rules! debug_assert {
($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
}
在Rust users forum上也对此进行了简要讨论,其中摘要是cfg(debug_assertions)
是检查我们是否处于调试模式的方法。
然而,我不知道稳定cfg(debug_assertions)
是多少。
答案 1 :(得分:3)
您将使用条件编译属性:
#[cfg(feature = "debugging")]
macro_rules! log {
() => { println!("Debugging") }
}
#[cfg(not(feature = "debugging"))]
macro_rules! log {
() => { }
}
fn main() {
log!();
}
在这里,您可以使用Cargo's "features"提供一个编译时参数来切换调试的实现。
但是,在这种情况下,没有要求使用宏:
#[cfg(feature = "debugging")]
fn log() { println!("Debugging") }
#[cfg(not(feature = "debugging"))]
fn log() {}
fn main() {
log();
}
在这种情况下,我非常信任优化器中生成相同的代码。