【问题标题】:Different versions of the same function with conditional compilation in RustRust 中具有条件编译的同一函数的不同版本
【发布时间】:2020-09-12 09:19:13
【问题描述】:

我正在尝试创建同一个函数的两个不同版本,其中只有一个会被编译。举个例子:

#[cfg(debug_assertions)]
fn do_something(x: usize) -> usize {
    x + 1
}

#[cfg(not(debug_assertions))]
fn do_something() -> usize {
    0
}

这很好用,我也可以调用do_something 的正确版本如果我知道我在调用哪一个(实际上,这些函数会做完全相同的事情,调试那个只是需要更多信息进行一些验证)。所以我可以创建两个对应的main函数:

#[cfg(debug_assertions)]
fn main() {
    do_something(0);
}

#[cfg(not(debug_assertions))]
fn main() {
    do_something();
}

但这很笨拙,我只想拥有一个不依赖于debug_assertions 的代码版本。我想做类似的事情:

macro_rules! call {
    ($func:ident, $optional_arg:expr) => {{
        if cfg!(debug_assertions) {
            $func($optional_arg);
        } else {
            $func();
        }
    }};
}

fn main() {
    call!(do_something, 0);
}

然后在我调用此函数或类似函数的任何地方重新使用宏。但这不会编译:

  --> main.rs:16:13
   |
2  | fn do_something(x: usize) -> usize {
   | ---------------------------------- defined here
...
16 |             $func();
   |             ^^^^^-- supplied 0 arguments

   |             |
   |             expected 1 argument
...
22 |     call!(do_something, 0);
   |     ----------------------- in this macro invocation
   |
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

我不明白为什么会出现错误,因为甚至不应该编译错误的函数调用。 可以通过强制函数具有相同的签名并简单地忽略发布版本中不必要的参数来修复错误,但这似乎不是正确的方法。

在这种情况下你会怎么做?为什么宏示例编译不出来?

【问题讨论】:

    标签: rust conditional-compilation


    【解决方案1】:

    来自reference

    cfg!#[cfg] 不同,它不会删除任何代码,只会计算 为真或假。例如,if/else 表达式中的所有块 当cfg! 用于条件时需要有效,无论 cfg! 正在评估什么

    标志将在编译时评估,但您在运行时进行此检查。你需要使用属性来避免这个问题:

    macro_rules! call {
        ($func:ident, $optional_arg:expr) => {{
            #[cfg(debug_assertions)]
            $func($optional_arg);
    
            #[cfg(not(debug_assertions))]
            $func();
        }};
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-27
      • 2021-11-08
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-09
      相关资源
      最近更新 更多