因此,回答这个问题最简单的方法就是退后一步,带你了解一生到底是什么。
让我们看一个简单的函数:
fn simple_function() {
let a = MyFoo::new();
println("{}", a);
}
在这个函数中,我们有一个变量,a
。该变量与所有变量一样,存在一定的时间。在这种情况下,它会一直存在到函数末尾。当函数结束时,a
死了。的寿命a
,则可以描述为从函数的开头开始,在函数的末尾结束。
下一个函数将无法编译:
fn broken_function() -> &MyFoo {
let a = MyFoo::new();
return &a;
}
当你这样做时&a
, 你是借用 a 参考 to a
。然而,借钱的问题在于,你应该归还借来的东西。 Rust对此非常严格,不会让你有无法返回的引用。如果你借用的参考资料已经不存在了,你就无法归还参考资料,这样就不行了。
这对我们意味着什么broken_function
是这样,因为a
在函数结束时死亡,引用无法转义该函数,因为这会使其持久a
.
下一步是这样的:
fn call_fn() {
let a = MyFoo:new();
{
let a_ref = &a;
let b = lifetimed(a_ref);
println!("{}", *b);
}
}
fn lifetimed<'a>(foo: &'a MyFoo) -> &'a MyBar {
return foo.as_bar();
}
这里有两个函数,call_fn
and lifetimed
,这里发生了一些微妙的事情,所以我将对其进行分解。
In call_fn
我首先创建一个新实例MyFoo
并将其分配给a
,那么,我借用一下参考a
并将其分配给a_ref
。借用的问题在于,当您进行借用时,生命周期信息将从您借用的变量传输到引用本身。所以现在a_ref
,作为一个变量,有它自己的生命周期,它在该内部作用域的开始和结束处开始和结束,但是a_ref
also有一生,从转移过来的a
.
具体的生命周期无法命名,但让我们假装我们可以通过使用数字来做到这一点。如果生命周期为a
is #1
,那么type of a_ref
is &'#1 MyFoo
。当我们经过a_ref
to lifetimed
,编译器填写生命周期参数'a
就像其他类型参数一样。lifetimed
的返回类型是具有相同生命周期的引用,因此编译器会填充那里的空间。有效地进行独特的呼叫lifetimed(foo: &'#1 MyFoo) -> &'#1 MyBar
.
这就是生命周期出现在类型参数列表中的原因,它们是类型系统的一部分,如果类型不匹配,则会出现错误。编译器会计算出函数编译所需的生命周期,因此您永远不必担心它,但也不会在当前函数之外查找以获取更多信息。您需要使用参数告诉编译器您正在调用的函数,以便编译器知道一切正常。
NB:您可以明确命名一个生命周期。'static
这是在整个程序期间持续的事物的生命周期。