为什么通用生命周期不符合嵌套作用域的较小生命周期?

为什么通用生命周期不符合嵌套作用域的较小生命周期?

问题描述:

根据 Rust编程语言 :

由于作用域始终嵌套,因此另一种说法是,通用生命周期'a 的具体生命周期等于 x 和 y .

Since scopes always nest, another way to say this is that the generic lifetime 'a will get the concrete lifetime equal to the smaller of the lifetimes of x and y.

fn main() {
    let x = "abcd";
    let result;
    {
        let y = "qwerty";
        result = longest(x, y);
    }
    println!("The longest string is {}  ", result);

}

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

在主函数中,"x和y的生命周期中的较小者"是嵌套作用域.这也应该是 result 中值的生命周期,但结果包含来自该嵌套作用域之外的正确值.

In the main function, "the smaller of the lifetimes of x and y" is the nested scope. This should be the lifetime of the value in result as well, but the result contains the correct value from outside of that nested scope.

为什么此代码正常工作?

Why does this code work correctly?

只有在谈论借用局部变量而获得的生命周期时,这才是正确的.在这种情况下,相关的生存期是字符串数据的生存期,对于字符串文字而言,该生存期为'static .换句话说,& str 指向存储在其他位置(特别是在静态数据段中)的数据,因此它们根本不会与堆栈生存期交互.

That's only true when talking about lifetimes derived from borrowing local variables. In this case, the relevant lifetime is the lifetime of the string data, which for string literals is 'static. In other words, the &strs are pointing to data stored elsewhere (in the static data segment, specifically), so they don't interact with stack lifetimes at all.

如果我们稍微更改示例,我们可以得出您期望的行为:

If we change the example slightly, we can induce the behaviour you're expecting:

fn main() {
    let x = "abcd";
    let result;
    {
        let y = "qwerty";
        result = longest(&x, &y);
    }
    println!("The longest string is {}  ", result);

}

fn longest<'a>(x: &'a &'static str, y: &'a &'static str) -> &'a &'static str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

编译失败的地方:

error[E0597]: `y` does not live long enough
  --> src/main.rs:6:35
   |
6  |             result = longest(&x, &y);
   |                                   ^ borrowed value does not live long enough
7  |         }
   |         - `y` dropped here while still borrowed
...
10 |     }
   |     - borrowed value needs to live until here

这失败了,因为现在我们正在讨论将借入堆栈.

This fails because now we're talking about borrows into the stack.