无法使用format_args!由于临时值在此语句结束时被释放

Phi*_*els 8 rust

我正在尝试构建自己的自定义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();
}
Run Code Online (Sandbox Code Playgroud)

我在调用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

Run Code Online (Sandbox Code Playgroud)

通常,这将是一个简单的修复 - 只需将临时变量放入局部变量即可。但在这种情况下,我不明白如何解决它,因为我已经将我能想到的所有内容都放入了局部变量中(这就是为什么我不认为这个问题与其他问题重复)。这似乎是format_args!宏观上特有的事情。

{}有趣的是,如果您在调用中不使用任何占位符,问题就会消失format_args!()

E_n*_*ate 10

format_args!预计将在使用返回值的地方准确调用。

let mut builder = RecordBuilder::new();
let _log_rec = builder
    .args(format_args!("Completed: {}, Elapsed={:?}", "blah", 20))
    .build();
Run Code Online (Sandbox Code Playgroud)

这是因为,按照其实现方式,宏会扩展为(以及其他构造)每个给定参数的一系列范围狭窄的值,并且Arguments创建该值时仅具有足够大的生命周期来捕获它们。