我正在努力理解生命周期。我理解(我认为)使用输入参数指定生命周期(即 foo<'a>(x: &'a String) -> &'a String {})意味着返回值继承输入参数的生命周期,因此将存在只要那样。然而,下面的代码在没有任何输入参数的情况下编译得很好,所以我不明白编译器是如何知道我希望对 Dragon::Green 的引用能够存在足够长的时间以离开范围。所有权是转移到了更高的范围,还是发生了其他事情?
fn main() {
let d;
{
let dtile = testtile();
d = dtile;
}
println!("{:?}", d);
}
#[derive(PartialOrd, Ord, PartialEq, Eq, Debug)]
enum Dragon {
White,
Green,
Red
}
fn testtile<'a>() -> &'a Dragon {
&Dragon::Green
}
用输入参数指定生命周期(即foo<'a>(x: &'a String) -> &'a String {})意味着返回值继承输入参数的生命周期
不完全是。生命周期说明符是 descriptive,而不是 prescriptive.
他们帮助 borrow checker 执行关于生命周期的规则。
每个引用都有生命周期。但有时您需要通过名称来引用该生命周期,这就是生命周期说明符的用武之地。
在您的示例中,发生的事情是借用检查器发现
testtile
返回的引用必须与变量 d 一样长。然后它会尝试找到一个 concrete 生命周期来替代通用生命周期参数 'a
,这将使它起作用。
在这种情况下,这确实有效。例如,如果我们指定引用具有
'static
生命周期,则没有问题。鉴于一个简单的枚举变体实际上只是一个常量,这里没有问题。
在更复杂的情况下,可能没有有效的方法来找到替代生命周期参数的生命周期,尽管这会更常见,例如,如果
Dragon
结构本身包含引用。