Rust 有调试宏吗?
Does Rust have a debug macro?
在 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 有类似的东西吗?
您可以自己定义它们,但使用 log
crate, which defines several macros for various purposes (see the log
documentation).
会更简单
请注意,该 crate 仅提供用于日志记录的 前端 ;您还需要 select 一个后端。 log
文档中有一个基本示例,或者您可以使用类似 env_logger
or log4rs
.
的内容
尽管使用 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
。
生锈 1.32.0
Rust 1.32.0 stabilized the dbg!()
宏,输出:
- 调用宏的文件名。
- 调用宏的行号。
- 参数的漂亮打印(必须实现
Debug
特征)。
注意: dbg!()
移动其参数,因此您可能希望通过引用传递非复制类型。
示例:点数组 (Playground)
#[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
}
]
示例:条件编译 (Playground)
OP表示希望仅在调试模式下编译时显示调试内容。
以下是实现此目的的方法:
#[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
Rust 1.32.0 之前
你可以 or you could .
基于 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!(...)
我没有找到替换为空的方法,但我认为编译器会做到这一点。
在 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 有类似的东西吗?
您可以自己定义它们,但使用 log
crate, which defines several macros for various purposes (see the log
documentation).
请注意,该 crate 仅提供用于日志记录的 前端 ;您还需要 select 一个后端。 log
文档中有一个基本示例,或者您可以使用类似 env_logger
or log4rs
.
尽管使用 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
。
生锈 1.32.0
Rust 1.32.0 stabilized the dbg!()
宏,输出:
- 调用宏的文件名。
- 调用宏的行号。
- 参数的漂亮打印(必须实现
Debug
特征)。
注意: dbg!()
移动其参数,因此您可能希望通过引用传递非复制类型。
示例:点数组 (Playground)
#[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
}
]
示例:条件编译 (Playground)
OP表示希望仅在调试模式下编译时显示调试内容。
以下是实现此目的的方法:
#[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
Rust 1.32.0 之前
你可以
基于 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!(...)
我没有找到替换为空的方法,但我认为编译器会做到这一点。