简体   繁体   English

在 Rust 中使用条件编译的相同函数的不同版本

[英]Different versions of the same function with conditional compilation in Rust

I'm trying to create two different versions of the same function, only one of which will be compiled.我正在尝试创建同一个函数的两个不同版本,只会编译其中一个。 As an example:举个例子:

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

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

This works fine and I can also call the correct version of do_something if I know which one I'm calling (In practice, the functions will do the exact same thing, the debug one just requires more info for some validation).这工作正常,如果我知道我正在调用哪个版本,我也可以调用正确版本的do_something (实际上,这些函数将做完全相同的事情,调试只需要更多信息进行一些验证)。 So I can create two corresponding main functions:所以我可以创建两个对应的main功能:

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

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

But this is very clumsy, and I want to have only one version of the code that doesn't depend on debug_assertions .但这非常笨拙,我只想拥有一个不依赖于debug_assertions的代码版本。 I'd like to do something like:我想做类似的事情:

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

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

and then re-use the macro wherever I call this function, or similar ones.然后在我调用此函数或类似函数的任何地方重新使用宏。 But this doesn't compile:但这不能编译:

  --> 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

I don't understand why I get the error, since the wrong function call shouldn't even be compiled.我不明白为什么会出现错误,因为错误的函数调用甚至不应该被编译。 The error can be fixed by forcing the functions to have the same signature and simply ignoring the unnecessary argument in the release version, but that doesn't seem like the right way to go.可以通过强制函数具有相同的签名并简单地忽略发布版本中不必要的参数来修复错误,但这似乎不是正确的方法。

What would you do in this situation?在这个情况下,你会怎么做? Why doesn't the macro example compile?为什么宏示例不能编译?

From the reference :参考

cfg! , unlike #[cfg] , does not remove any code and only evaluates to true or false.#[cfg] ,它不会删除任何代码,只会评估为真或假。 For example, all blocks in an if/else expression need to be valid when cfg!例如,当cfg!时,if/else 表达式中的所有块都需要有效cfg! is used for the condition, regardless of what cfg!用于条件,不管cfg! is evaluating正在评估

Flags will be evaluated in compile time but you are doing this check at runtime.标志将在编译时进行评估,但您是在运行时进行此检查。 You need to use attributes to avoid the problem:您需要使用属性来避免该问题:

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

        #[cfg(not(debug_assertions))]
        $func();
    }};
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM