外观
雷区 8:E0716 借了一个"一次性的临时值"
报错码:E0716
症状
rust
fn get_first(s: &str) -> &str {
&s[..1]
}
fn main() {
let first = get_first(&String::from("hello"));
println!("{}", first);
}编译输出
text
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:6:28
|
6 | let first = get_first(&String::from("hello"));
| ^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary value which is freed while still in use
7 | println!("{}", first);
| ----- borrow later used here诊断
借了一个"借完就扔"的东西。
&String::from("hello") 里的 String::from("hello") 是临时值(temporary):这一行语句一结束,它就被清理。可 get_first 返回的借条还指着它——first 要用,临时值却已经没了。
看报错的两个关键词:creates a temporary value(造了个临时值)和 freed at the end of this statement(这一句结束就被释放)——借条比临时值活得久。
真实项目的高频姿势:方法链里顺手取借用——foo.bar().baz() 的中间结果、&format!(...)、&vec![...]……一句话里"造一个用完就扔的东西,还想借它"。
解药
解药一:先绑定,再借用——给临时值一个"长期户口":
rust
fn get_first(s: &str) -> &str {
&s[..1]
}
fn main() {
let owned = String::from("hello");
let first = get_first(&owned);
println!("{}", first);
}owned 活到 main 结束,借条稳稳的。
解药二:让函数"拥有"输入——临时值不是问题,问题是借了它;改成接收拥有值:
rust
fn get_first_owned(s: String) -> String {
s[..1].to_string()
}
fn main() {
let first = get_first_owned(String::from("hello"));
println!("{}", first);
}解药三:方法链里拆开写——把链条断成几步,中间结果落户口:
rust
fn main() {
let full = format!("{}!", "hello");
let first = &full[..1];
println!("{}", first);
}预防
- 看到 E0716,先找"临时值":报错里的
temporary value就是那个"一句话里造出来、一句话结束就没了"的东西 - 口诀:想借,先落户——
let 名字 = 值;之后再&名字,天下太平 - 方法链里需要借用中间结果时,拆开写;需要拥有时,
.to_owned()/.to_string()变一份自己的 &format!(...)是经典陷阱:format 的结果是临时值,借了必炸——要么先let s = format!(...),要么直接拥有