对指针及其指向的结构的生存期参数使用相同的生存期

问题描述 投票:3回答:1

请考虑以下内容:

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的寿命。

然后我写了f1,它使用单个生命周期参数,怀疑生命周期'a指的是&mut a生命周期和&s生命周期中的较短者。

但是,此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

该错误使我感到困惑:为什么在调用a之后仍然借用f1作为可变的?

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

rust lifetime borrowing
1个回答
0
投票

为什么在调用a之后仍将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的范围相关联,这意味着f1a的整个范围内都借用了s

这对于不可变的引用不是问题,因为更长的寿命可能被强制转换为较短的寿命;换句话说,不变引用的生存期为covariant。但是mutable引用的生存期是invariant。这意味着它们不能被强制缩短(或更长)的寿命。

© www.soinside.com 2019 - 2024. All rights reserved.