固定示例:
fn main() {
let strA = "a".to_string();
let result;
{
let strB = "abc".to_string();
result = longest(&strA, &strB); // Will return strB
}
println!("The longest string is {}", result); // compile error
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
现在按预期产生编译器错误:
error[E0597]: `strB` does not live long enough
--> src/main.rs:7:33
|
7 | result = longest(&strA, &strB); // Will return strB
| ^^^^^ borrowed value does not live long enough
8 | }
| - `strB` dropped here while still borrowed
9 |
10 | println!("The longest string is {}", result); // result now point to strB!!
| ------ borrow later used here
playground
Rust 在您的初始示例中没有“忽略”字符串变量的生命周期。当您将变量设置为字符串文字时,该文字会被硬编码到可执行二进制文件中并获得'static 生命周期,这意味着它在程序的整个持续时间内都有效。如果我们在您的初始示例中添加显式类型注释,则应该清楚它为什么编译和工作:
fn main() {
let strA: &'static str = "a";
let result;
{
let strB: &'static str = "abc";
result = longest(&strA, &strB); // returns 'static str
}
println!("The longest string is {}", result); // prints result
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() {
x
} else {
y
}
}
但是,当我们在字符串文字上调用 to_string() 时,我们会创建一个拥有和堆分配的 String,其生命周期是非静态的,并且作用域为它所在的任何块,因此进行更改会使程序不再编译为预计。