英文:
Why does specifying a lifetime let me return a reference?
问题
I'm struggling to understand lifetimes. I understand (I think) that specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {})
means that the returned value inherits the lifetime of the input parameter and will therefore live as long as that does. However, the code below compiles just fine without any input parameters, so I don't understand how the compiler knows I wanted the reference to Dragon::Green
to live long enough to leave scope. Is the ownership getting moved to a higher scope, or is something else happening?
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
}
英文:
I'm struggling to understand lifetimes. I understand (I think) that specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter and will therefore live as long as that does. However, the code below compiles just fine without any input parameters, so I don't understand how the compiler knows I wanted the reference to Dragon::Green to live long enough to leave scope. Is the ownership getting moved to a higher scope, or is something else happening?
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
}
答案1
得分: 3
specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter
不完全正确。生命周期标识符是 描述性 的,而不是 规定性 的。
它们帮助 借用检查器 强制执行有关生命周期的规则。
每个引用都有一个生命周期。但有时你需要通过名称引用那个生命周期,这就是生命周期标识符的作用所在。
在你的例子中,发生的情况是,借用检查器看到 testtile
返回的引用必须与变量 d
一样长寿。然后它尝试找到一个 具体的 生命周期来替代泛型生命周期参数 'a
,使其可以正常工作。
在这种情况下,的确可以正常工作。例如,如果我们指定引用具有 'static
生命周期,就没有问题。而且考虑到一个简单的枚举变量实际上只是一个常数,这里就没有问题。
在更复杂的情况下,可能找不到可以替代生命周期参数的有效生命周期,尽管这在更常见的情况下可能是因为,例如,Dragon
结构体本身 包含 引用。
英文:
> specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter
Not quite. Lifetime specifiers are descriptive, not prescriptive.
They help the borrow checker enforce rules around lifetimes.
Every reference has a lifetime. But sometimes you need to refer to that lifetime by name, and that's where lifetime specifiers come in.
In your example, what's happening is that the borrow checker sees that the reference returned by testtile
must live as long as variable d. It then tries to find a concrete lifetime to substitute for the generic lifetime parameter 'a
that would make that work.
In this case, that does indeed work. For example, if we specify that the reference has 'static
lifetime, there's no problem. And given that a simple enum variant is really just a constant, there's no issue here.
In more complex cases, it might be that there's no valid way to find a lifetime to substitute for the lifetime parameter, though this would be more common if, for example, the Dragon
struct itself contained references.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论