我正在尝试构建自己的自定义LogRecord并将其传递到log板条箱中。
use log::RecordBuilder;
fn main() {
let msg = format_args!("Completed: {}, Elapsed={:?}", "blah", 20);
//let msg = format_args!("This is OK");
let mut builder = RecordBuilder::new();
let _log_rec = builder
.args(msg)
.build();
}
调用args方法遇到了一个临时的生命周期问题。错误是
--> src/main.rs:4:28
|
4 | let msg = format_args!("Completed: {}, Elapsed={:?}", "blah", 20);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
...
8 | .args(msg)
| --- borrow later used here
|
= note: consider using a `let` binding to create a longer lived value
通常,这很容易解决-只需将临时变量放入本地变量即可。但是在这种情况下,我不知道如何解决它,因为我已经将所有可以想到的东西都放入了局部变量中(这就是为什么我不认为这个问题是其他问题的重复)。这似乎是format_args!
宏所特有的。
有趣的是,如果在对{}
的调用中不使用任何format_args!()
占位符,问题就会消失。
E_net4中的解决方案是正确的。在我的实际代码中,它不能立即起作用:
impl Drop for ExecutionTimer2 {
fn drop(&mut self) {
let elapsed = self.start_time.elapsed();
let mut builder = RecordBuilder::new();
let log_rec = builder
.level(Level::Debug)
.target("ExecutionTimer")
.file(Some(self.file))
.module_path(Some(self.module_path))
.line(Some(self.line))
.args(format_args!("Completed: {}, Elapsed={:?}", self.name, elapsed))
.build();
let logger = log::logger();
logger.log(&log_rec);
}
}
但是我再次应用了“内联”技术来产生这段代码,该代码可以编译:
impl Drop for ExecutionTimer2 {
fn drop(&mut self) {
let elapsed = self.start_time.elapsed();
let mut builder = RecordBuilder::new();
let logger = log::logger();
logger.log(&
builder
.level(Level::Debug)
.target("ExecutionTimer")
.file(Some(self.file))
.module_path(Some(self.module_path))
.line(Some(self.line))
.args(format_args!("Completed: {}, Elapsed={:?}", self.name, elapsed))
.build()
);
}
}
答案 0 :(得分:2)
format_args!
将在将使用返回值的确切位置被调用。
let mut builder = RecordBuilder::new();
let _log_rec = builder
.args(format_args!("Completed: {}, Elapsed={:?}", "blah", 20))
.build();
这是因为,宏的实现方式(对于其他构造而言)扩展为一系列给定参数的范围狭窄的值,并且Arguments
值的创建只有足够长的生存期捕获它们。