簡體   English   中英

在 Rust 中使用條件編譯的相同函數的不同版本

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

我正在嘗試創建同一個函數的兩個不同版本,只會編譯其中一個。 舉個例子:

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

我不明白為什么會出現錯誤,因為錯誤的函數調用甚至不應該被編譯。 可以通過強制函數具有相同的簽名並簡單地忽略發布版本中不必要的參數來修復錯誤,但這似乎不是正確的方法。

在這個情況下,你會怎么做? 為什么宏示例不能編譯?

參考

cfg! #[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();
    }};
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM