You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中引用的生命周期(lifetime)问题:`e = &***c`时`e`的生命周期解析

Rust中引用的生命周期(lifetime)问题:e = &***c时e的生命周期解析

首先先看对应的代码示例:

fn lifetime_test<'a>(s: &'a String, t: &'a String) -> &'a String {
    s
}

fn main() {
    // let a;
    let mut a = String::from("hello1");
    let b = &mut a;
    let e;
    {
        let c = &b;
        // e = c;  // OK, move
        e = &***c; // OK, but why?
        // e = &*b; // OK, is *b same as a?
        // e = &a; // err, sure, a is borrowed
        // e = &c; // err, c lives not long enough
        // e = lifetime_test(c, b); // OK, because auto-dereference
        println!("{c}");
    }
    println!("{b}");
    // b.push_str("string");
    let d = &b;
    println!("{d} {e}");
    b.push_str("hello2");
    a.push_str("hello3");
    // println!("{}", l);

}

问题核心

What is the lifetime of e when e = &***c?

原提问者的前置理解

  • b is a mutable reference to a, and c is an immutable reference to b.
  • I know that dereferencing c three times (&***c) should give me a reference to a (really?). But I’m unsure about how the lifetime of the reference e works here.
  • I understand that c itself is valid within the inner scope, and b is valid throughout the function. But I’m confused about why e = &***c works while e = &c gives an error (because c doesn’t live long enough).

详细解析

Let's break this down in plain, approachable terms:

First, let's map out all references and their lifespans clearly:

  1. a is the original String instance, created at the start of main and alive until the function ends.
  2. b is a mutable reference to a (&mut a), so its lifetime is directly tied to a—it's valid for the entire main function.
  3. c is an immutable reference to b (&b), but it's declared inside the inner curly brace scope, so it dies as soon as that scope closes.

Now let's unpack what &***c actually does, step by step:

  • *c gives us the value of b (the mutable reference &mut a), since c points directly to b.
  • **c gives us the value that b points to: the original String a.
  • ***c might look like we're dereferencing a (which isn't a reference, so that shouldn't compile)—but Rust's auto-dereferencing rules kick in here to collapse redundant operations. When you write &***c, Rust treats it as a direct reference to the ultimate target of the chain: a.

The critical "aha" moment is lifetime inheritance:

  • When you write &c, you're creating a reference to c itself. Since c only lives inside the inner scope, this reference's lifetime can't extend past that scope—hence the "c does not live long enough" error.
  • When you write &***c, you're creating a reference to a, not to c or b. The lifetime of this new reference is tied to a (or to b's reference to a, which matches a's lifetime), not to c. Even though c dies at the end of the inner scope, e is pointing directly to a—which is still alive for the rest of main.

A quick side note on why &***c is allowed when &a gives an error: a is already borrowed mutably by b, and Rust normally blocks mutable and immutable references from coexisting. But &***c is derived from the mutable reference b, so Rust's borrow checker recognizes this immutable reference is aliasing through b—and since we're not using e to mutate anything (and the mutable reference b is still usable later), it's permitted.

To answer your core question directly:

What is the lifetime of e when e = &***c?

The lifetime of e is the entire duration of the main function, matching the lifetime of a (and b). It's not tied to c at all—because e is ultimately a reference to the original String instance, not to any of the intermediate references in the chain.

You can confirm this by observing that e is used long after the inner scope closes (in println!("{d} {e}")) and that you can still modify a and b later—something that would be impossible if e's lifetime was tied to c.


备注:内容来源于stack exchange,提问作者htam_ujn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:00:33