3.6 无界生命周期

无界生命周期及其危险性

译文 · 基于 The Rustonomicon

无界生命周期

原文链接: https://doc.rust-lang.org/nomicon/unbounded-lifetimes.html

  Unsafe 代码常常凭空产生引用或生命周期。   这类生命周期以无界(unbounded)的形式出现。最常见的来源是对解引用后的裸指针取引用,由此得到的引用具有无界生命周期。这种生命周期会随上下文需要而「撑大」。事实上它比单纯变成 'static 更强大——例如 &'static &'a T 会类型检查失败,而无界生命周期却能按需完美适配为 &'a &'a T。不过对大多数意图和目的而言,无界生命周期可以视为 'static。

  几乎没有任何引用真的是 'static,因此这很可能是错误的。transmute 和 transmute_copy 是另外两大「惯犯」。应尽可能尽快为有界生命周期加上约束,尤其跨越函数边界时。

  给定一个函数,任何不来自输入的输出生命周期都是无界的。例如:

fn get_str<'a>(s: *const String) -> &'a str {
    unsafe { &*s }
}

fn main() {
    let soon_dropped = String::from("hello");
    let dangling = get_str(&soon_dropped);
    drop(soon_dropped);
    println!("Invalid str: {}", dangling); // Invalid str: gӚ_`
}

  避免无界生命周期最简便的方法是在函数边界使用生命周期省略。若输出生命周期被省略,则它必须由某个输入生命周期约束。当然,它可能被错误的生命周期约束,但这通常只会导致编译错误,而非轻易破坏内存安全。

  在函数内部,为生命周期加上约束更容易出错。最安全、最简便的方式是从带有有界生命周期的函数返回它。若这不可接受,可将引用放入具有特定生命周期的位置。遗憾的是,无法为函数中涉及的所有生命周期都命名。

最后修改 August 11, 2026: 更新 (70a5af133)