如何重新定义宏?

时间:2015-06-11 16:47:15

标签: rust

在C ++中,您可以取消定义并重新定义宏。 例如,视频游戏中常见的事情是在发布模式下将日志记录宏重新定义为空。这可以保证代码完全消失,这有助于提高性能。

有没有办法在Rust中做类似的事情?

2 个答案:

答案 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();
}

在这种情况下,我非常信任优化器中生成相同的代码。