为什么借用的字符串字面量可以通过伪造寿命比其所有者长寿?

Why can borrowed string literal outlive its owner by faking a lifetime?

我明白借用不能比它指向的东西存在更久,以消除悬空指针。

通过伪造生命周期,借用或别名可以比所有者更长久:

fn main() {
    let e;
    let first = "abcd";
    {
        let second = "defgh";
        e = longest(first, second);
    }
    println!("{}", e);
}

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

结果:

defgh

在上面的例子中,变量 e 的生命周期比 second 变量长,显然 firstsecond 变量的生命周期是不同的。

当使用 longest(first, second) 初始化 e 时,它会得到 second 变量,其函数调用的生命周期被伪造为等于 first 但它仅限于该块并将其分配给 e,它将比 second 更有效。为什么这样可以?

这是因为它们都具有 'static 生命周期。

这是一个不起作用的示例,因为这里的 str 不像 &'static str 那样在程序的生命周期内存在。 唯一的变化是以下行:let second = String::from("defgh"); 以及传递给最长函数的下一行。

fn main() {
    let e;
    let first = "abcd";
    {
        let second = String::from("defgh");
        e = longest(first, &second);
    }
    println!("{}", e);
}

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

这是错误:

error[E0597]: `second` does not live long enough
 --> src/main.rs:6:28
  |
6 |         e = longest(first, &second);
  |                            ^^^^^^^ borrowed value does not live long enough
7 |     }
  |     - `second` dropped here while still borrowed
8 |     println!("{}", e);
  |                    - borrow later used here

可以在 Static - Rust By Example

中找到更多信息