rust - 不能使用 format_args!由于临时值在此语句的末尾被释放
问题描述
我正在尝试构建自己的自定义LogRecord并将其传递到日志箱中。
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()
);
}
}
解决方案
format_args!
预计将在使用返回值的确切位置调用。
let mut builder = RecordBuilder::new();
let _log_rec = builder
.args(format_args!("Completed: {}, Elapsed={:?}", "blah", 20))
.build();
这是因为,按照它的实现方式,宏扩展为(在其他结构中)每个给定参数的一系列范围狭窄的值,并且Arguments
创建的值只有足够大的生命周期来捕获它们。
推荐阅读
- android-studio - 如何从 GitHub 构建示例 Android 位置应用程序
- javascript - 在表中渲染多个组件反应
- domain-driven-design - ddd中上游上下文和下游上下文的关系
- c - 2 的不同幂的十进制和十六进制表示
- python - 使用带有 OpenCV 运动跟踪的 IP 网络摄像头
- python - 将另一个数组与一个充满数组的列表进行比较
- parquet - http request with parquet and pyarrow
- python - 根据数据来源的 url 组织抓取的数据
- java - 如何使用 Mockito 模拟并使用 Junit5 断言抛出的异常和消息?
- reactjs - 如何将我的状态从对象转换为可映射数组?