对指针和它指向的结构的生命周期参数使用相同的生命周期

Using the same lifetime for the pointer and the lifetime parameter of the struct it points to

考虑以下因素:

struct Str<'a> {
    s: &'a str,
}

fn f1<'a>(_: &'a mut Str<'a>) {}

fn f2<'a, 'b>(_: &'a mut Str<'b>) {}

fn main() {
    let s = "hello".to_string();
    let mut a = Str {
        s: &s,
    };

    f1(&mut a);
    // f2(&mut a);

    let t: &Str = &a;
}

f2 使用两个不同的生命周期,就像我删除它们时一样,效果很好。

此时我以为生命周期'a指的是&mut a的生命周期,'b指的是&s的生命周期。[=24] =]

然后我写了f1,它使用了一个生命周期参数,怀疑生命周期'a指的是&mut a的生命周期和[=16的生命周期中较短的一个=].

但是,此 f1 失败并出现以下错误:

error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src/main.rs:21:19 
   |
18 |     f1(&mut a);
   |        ------ mutable borrow occurs here
...
21 |     let t: &Str = &a;
   |                   ^^
   |                   |
   |                   immutable borrow occurs here
   |                   mutable borrow later used here

错误让我很困惑:为什么在调用f1a仍然被借用为可变的?

为什么会失败,错误消息是什么意思?

Why is a still borrowed as mutable after calling f1?

fn main() {
    //                  scope of s ---\
    let s = "hello".to_string(); //   |
    let mut a = Str {            //   |
        s: &s,                   //   |
    };                           //   |
                                 //   |
    //        f1 borrows a until ---\ |
    f1(&mut a);                  // | | 
    // but it's used here \         | |
    let t: &Str = &a; //  X      // | |
                                 // X X
}

s的范围到main结束为止。由于 f1 参数上的生命周期注释,可变引用 &mut a 的生命周期与 s 的范围相关联,这意味着 f1 正在借用 [=11] =] 用于 s.

的整个范围

这不是不可变引用的问题,因为更长的生命周期可能会被强制转换为更短的生命周期;换句话说,不可变引用的生命周期是协变。但是 mutable 引用的生命周期是 invariant。这意味着他们不能被迫缩短(或延长)寿命。