此代码无法编译,因为 rust 需要添加生命周期。
fn firstNoLifetime(x: &str, y: &str) -> &str {
return x;
}
Run Code Online (Sandbox Code Playgroud)
因此,我们必须像这样显式添加生命周期:
fn first<'a>(x: &'a str, y: &'a str) -> &'a str {
return x;
}
Run Code Online (Sandbox Code Playgroud)
那么我的问题是,这个没有生命周期的函数是如何编译的?
为什么泛型函数不需要生命周期,有什么注意事项吗?
fn first_generic<A>(x: A, y: A) -> A {
return x;
}
Run Code Online (Sandbox Code Playgroud)
我的假设是,生命周期注释可以帮助编译器和借用检查器确定生命周期违规的根本原因,但在下面的代码中,rust 能够在没有注释的情况下确定原因。我的假设是错误的吗?如果是这样,生命周期注释的目的是什么?
fn first_generic<A>(x: A, y: A) -> A {
return x;
}
fn main() {
let string1 = String::from("long string is long");
let result: &str;
{
let string2 = String::from("xyz");
result = first_generic(string1.as_str(), string2.as_str());
}
println!("The first string is: {}", result);
}
Run Code Online (Sandbox Code Playgroud)
结果:
|
10 | result = first_generic(string1.as_str(), string2.as_str());
| ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
11 | }
| - `string2` dropped here while still borrowed
12 |
13 | println!("The first string is: {}", result);
| ------ borrow later used here
Run Code Online (Sandbox Code Playgroud)
生命周期是类型本身的一部分
'a在第一个示例中,您为所有x,和返回值指定相同的 ie y。如果您收到单个值作为参考,则不必传递生命周期说明符,对吧?
fn first(x: &str) -> &str {
x
}
Run Code Online (Sandbox Code Playgroud)
这是因为编译器会自行推断两者的生命周期。
回到你的问题,“为什么通用函数不需要生命周期”,简短的回答是,他们需要。只是不在您提供的示例中。为什么?
在第二个示例中,您展示了x,y并且返回值必须具有与所有值相同的类型A。提醒一下,生命周期是类型本身的一部分,这里只有一个生命周期发挥作用,因此编译器可以自行推断它。
我的假设是生命周期注释帮助编译器和借用检查器确定生命周期违规的根本原因,
是的,你的假设也是正确的。在这种情况下,生命周期注释确实可以帮助编译器和借用检查器确定生命周期违规的根本原因。
但在下面的代码中,rust 能够在没有注释的情况下确定原因
如上所述,这里只有一个生命周期,因此 Rust 能够自行推断。然而,在某些旧版本的 rust 编译器中,情况并非如此(我不记得确切的版本,但当时,我们也必须在通用情况下指定生命周期注释)