在C++中,我使用类似这样的DEBUG
宏:
#ifdef DEBUG
#define DEBUG_STDERR(x) (std::cerr << (x))
#define DEBUG_STDOUT(x) (std::cout << (x))
#else
#define DEBUG_STDERR(x)
#define DEBUG_STDOUT(x)
#endif
Rust有类似的东西吗?
在C++中,我使用类似这样的DEBUG
宏:
#ifdef DEBUG
#define DEBUG_STDERR(x) (std::cerr << (x))
#define DEBUG_STDOUT(x) (std::cout << (x))
#else
#define DEBUG_STDERR(x)
#define DEBUG_STDOUT(x)
#endif
Rust有类似的东西吗?
Rust 1.32.0稳定了dbg!()
宏,该宏输出:
Debug
trait)。注意:dbg!()
移动其参数,因此您可能希望通过引用传递非复制类型。
#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let points = [
Point { x: 0, y: 0 },
Point { x: 2, y: 3 },
Point { x: 5, y: 7 },
];
dbg!(&points);
}
程序输出
[src/main.rs:14] &points = [
Point {
x: 0,
y: 0
},
Point {
x: 2,
y: 3
},
Point {
x: 5,
y: 7
}
]
原帖提到只想在调试模式下显示调试内容。
以下是实现此功能的一种方法:
#[cfg(debug_assertions)]
macro_rules! debug {
($x:expr) => { dbg!($x) }
}
#[cfg(not(debug_assertions))]
macro_rules! debug {
($x:expr) => { std::convert::identity($x) }
}
fn main() {
let x = 4;
debug!(x);
if debug!(x == 5) {
println!("x == 5");
} else {
println!("x != 5");
}
}
程序输出(调试模式)
---------------------Standard Error-----------------------
[src/main.rs:13] x = 4
[src/main.rs:14] x == 5 = false
---------------------Standard Output----------------------
x != 5
程序输出(发布模式)
---------------------Standard Output----------------------
x != 5
你可以使用 log crate,或者自己定义一个。
虽然像DK的答案提到的使用log
组件是有意义的,但以下是如何直接实现你所要求的等效方法:
// The debug version
#[cfg(feature = "my_debug")]
macro_rules! debug_print {
($( $args:expr ),*) => { println!( $( $args ),* ); }
}
// Non-debug version
#[cfg(not(feature = "my_debug"))]
macro_rules! debug_print {
($( $args:expr ),*) => {}
}
fn main() {
debug_print!("Debug only {}", 123);
}
在您的 Cargo.toml
文件中,添加一个 [features]
部分:
[features]
my_debug = []
使用cargo run --features my_debug
命令运行程序可以看到输出,而使用普通的cargo run
则看不到。
debug_assertions
属性来使得这段代码更加简洁,该属性可以控制像 debug_assert!
这样的宏。只需将 #[cfg(feature = "my_debug")]
更改为 #[cfg(debug_assertions)]
并删除对 Cargo.toml
的更改。这样,在发布版本中,调试代码就会自动被忽略! - CJ McAllisterlog
crate会更简单,该crate为各种目的定义了几个宏(请参见 log
文档)。log
文档中有一个基本示例,或者您可以使用类似于env_logger
或log4rs
之类的工具。基于Chris Emerson的回答和CJ McAllister的评论的宏
// Disable warnings
#[allow(unused_macros)]
// The debug version
#[cfg(debug_assertions)]
macro_rules! log {
($( $args:expr ),*) => { println!( $( $args ),* ); }
}
// Non-debug version
#[cfg(not(debug_assertions))]
macro_rules! log {
($( $args:expr ),*) => {()}
}
使用
log!("Don't be crazy");
log!("Answer is {}", 42);
使用cargo build --release
进行构建将会将所有的log!(...)
替换为单元元组();
我没有找到替换为空的方法,但我认为编译器会自动处理。
dbg!
旨在用于调试和发布版本。官方文档明确说明了其目的:请注意,该宏旨在作为调试工具使用,因此您应避免长时间在版本控制中使用它。对于需要添加到版本控制的调试输出的用例,最好使用log
包中的debug!
等宏来实现。 - legends2kdbg!
还会返回其参数(这就是为什么它必须将其移动)因此它可以用于包装任何表达式(只要它的类型是Debug
)。 - BallpointBen