链接 self 的生命周期和方法中的引用

Linking the lifetimes of self and a reference in method

我有 this piece of code:

#[derive(Debug)]
struct Foo<'a> {
    x: &'a i32,
}

impl<'a> Foo<'a> {
    fn set(&mut self, r: &'a i32) {
        self.x = r;
    }
}

fn main() {
    let v = 5;
    let w = 7;
    let mut f = Foo { x: &v };

    println!("f is {:?}", f);

    f.set(&w);

    println!("now f is {:?}", f);
}

我的理解是,在第一次借用[=13=的值时,struct声明的泛型生命周期参数'a填入了[=13=的值的生命周期] ].这意味着生成的 Foo 对象的寿命不得超过此 'a 的生命周期,或者 v 的值必须至少与 Foo 对象的寿命一样长。

在方法set的调用中,使用了impl块上的lifetime参数,为[=14=填写了w的值的lifetime ] 在方法签名中。 &mut self 被编译器分配了不同的生命周期,这是 fFoo 对象)的生命周期。如果我在 main 函数中切换 wf 的绑定顺序,这将导致错误。

我想知道如果我在 set 方法中使用与 r 相同的生命周期参数 'a 注释 &mut self 引用会发生什么:

impl<'a> Foo<'a> {
    fn set(&'a mut self, r: &'a i32) {
        self.x = r;
    }
}

这会导致以下错误:

error[E0502]: cannot borrow `f` as immutable because it is also borrowed as mutable
  --> src/main.rs:21:31
   |
19 |     f.set(&w);
   |     - mutable borrow occurs here
20 | 
21 |     println!("now f is {:?}", f);
   |                               ^ immutable borrow occurs here
22 | }
   | - mutable borrow ends here

与上面的例子相反,f 在第二个 println! 时仍然被认为是可变借用的!被调用,所以它不能作为不可变的同时被借用。

这是怎么发生的?

通过不遗漏生命周期注释,编译器为我在第一个示例中为 &mut self 填充了一个。这是根据生命周期省略规则发生的。但是,通过在第二个示例中将其显式设置为 'a,我将 f 的值和 w.

的值的生命周期联系起来

f不知何故被认为是自己借用的?

如果是这样,借用的范围是什么?是最小值([=25= 的生命周期],w 的生命周期)-> f 的生命周期?

我想我还没有完全理解函数调用中的 &mut self 引用。我的意思是,函数returns,但是f仍然被认为是借用的。

我正试图完全理解生命周期。我主要是在寻找有关我对这些概念的理解的纠正反馈。非常感谢您的每一条建议和进一步的说明。

In the call to the method set the lifetime parameter on the impl block is used and the lifetime of the value of w is filled in for 'a in the method signature.

没有。生命周期参数 'a 的值在 Foo 结构的创建时固定,并且永远不会改变,因为它是其类型的一部分。

在您的情况下,编译器实际上为 'a 选择了一个与 vw 的生命周期兼容的值。如果那不可能,它将失败,例如在这个例子中:

fn main() {
    let v = 5;
    let mut f = Foo { x: &v };

    println!("f is {:?}", f);
    let w = 7;
    f.set(&w);

    println!("now f is {:?}", f);
}

输出:

error[E0597]: `w` does not live long enough
  --> src/main.rs:21:1
   |
18 |     f.set(&w);
   |            - borrow occurs here
...
21 | }
   | ^ `w` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

正是因为 v 强加的 'a 生命周期与 w 的较短生命周期不兼容。

在第二个示例中,通过强制 self 的生命周期也为 'a,您也将可变借用绑定到生命周期 'a,因此当生命周期 'a 的所有项目超出范围时,借用结束,即 vw.