[英]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.