假设我有一个简单的日志记录特征:
pub trait Log {
fn log(&mut self, _message: &str) {}
}
我可能会编写一个函数来使用它:
pub fn output_int(x: i32, log: &mut impl Log) {
log.log(&format!("Writing value: {}", x));
// Do something with x
}
然而,这有一个缺陷:即使我使用静态分派,并使用
--release
,呼叫
format!()
没有被优化掉(
godbolt
可以使用
should_log()
-style方法,然后将其编译为空:
pub trait Log {
fn log(&mut self, _message: &str) {}
fn should_log(&self) -> bool { false }
}
pub fn output_int(x: i32, log: &mut impl Log) {
if log.should_log() {
log.log(&format!("Writing value: {}", x));
}
// Do something with x
}
struct NopLog {}
impl Log for NopLog {}
pub fn main() {
let mut log = NopLog{};
output_int(3, &mut log);
}
macro_rules! log {
($log:ident, $($arg:tt)*) => {
if $log.should_log() {
$log.log(&format!($($arg)*));
}
};
}
pub fn output_int(x: i32, log: &mut impl Log) {
log!(log, "Writing value: {}", x);
// Do something with x
}
它很管用,但还是觉得有点老土。我只是想看看-我是不是错过了一些简单明了的电话解决方案
格式!()
同时也允许将其优化为nop?