在调试模式下(cfg!(debug_assertions)
),我有一个结构体Foo
有2个字段{a:i16,only_in_debug:i16}
在释放模式下,结构体有一个字段{a:i16}
。
sum
函数在调试模式下为only_in_debug
字段增加一个数字,但在发布模式下不做任何事情(该字段缺失)。
我写了一个宏,但在发布模式下不工作:
macro_rules! sum {
($a:expr,$b:expr)=>{
if cfg!(debug_assertions) {
$a+=$b;
}
}
}
结构在调试模式
#[cfg(debug_assertions)]
#[derive(Debug)]
pub struct Foo {
pub a: i16,
pub only_in_debug: i16,
}
#[cfg(debug_assertions)]
impl Default for Foo {
fn default() -> Foo {
Foo {
a: 0,
only_in_debug: 0,
}
}
}
struct in release mode
#[cfg(not(debug_assertions))]
pub struct Foo {
pub a: i16,
}
#[cfg(not(debug_assertions))]
impl Default for Foo {
fn default() -> Foo {
Foo {
a: 0
}
}
}
主:
fn main() {
let mut foo = Foo::default();
sum!(foo.only_in_debug, 10);
println!("{:?}", foo); // (**)
}
在调试模式下运行,行(**)打印:Foo { a: 0, only_in_debug: 10 }
但在释放模式下显示^^^^^^^^^^^^^ unknown field
。
在C语言中,它使用预处理器宏
#ifdef NDEBUG
#define sum(a, b)
#else
#define sum(a, b) (a+=(b))
#endif
cfg!
宏将在编译时求值为true
或false
,但if
中的代码将始终被编译,因此必须进行类型检查。如果您希望在cfg
计算结果为false时不编译代码,则需要将#[cfg()]
属性附加到表达式:
macro_rules! sum {
($a:expr, $b:expr)=>{
#[cfg(debug_assertions)] {
$a += $b;
}
}
}
的例子:
struct Foo {
x: i32,
}
fn main() {
let foo = Foo { x: 1 };
// This fails to compile.
// if cfg!(target_pointer_width = "8") {
// foo.y;
// }
#[cfg(target_pointer_width = "8")]
{
foo.y;
}
}
游乐场