将自我的生命周期与方法中的参考联系起来

时间:2015-05-16 09:11:48

标签: rust

我有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);
}

我的理解是,在第一次借用v的值时,结构声明中的泛型生命周期参数'a将填充v值的生命周期。这意味着生成的Foo对象的生命周期不得超过此'a生命周期,或者v的值必须至少与Foo对象一样长。

在对方法set的调用中,使用impl块上的生命周期参数,并填充w的值'a的生命周期方法签名。编译器为&mut self分配了不同的生命周期,这是fFoo对象)的生命周期。如果我在w函数中切换fmain的绑定顺序,则会导致错误。

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

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在第二次打印时仍被认为是可变借用的!被称为,因此它不能作为不可变的同时借用。

这是怎么来的?

通过不离开生命周期注释,编译器在第一个示例中为我&mut self填充了一个。这通过终身省略规则发生。但是,通过在第二个示例中将其明确设置为'a,我将f的值的生命周期与w的值相关联。

f是否被认为是以某种方式借用的?

如果是这样,借款的范围是什么?是min(f的生命周期,w的生命周期) - &gt;生命周期为f

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

我想要充分了解生命。我主要是在寻找对我的概念理解的纠正反馈。我很感激你的每一点建议和进一步的澄清。

1 个答案:

答案 0 :(得分:3)

  

在方法set的调用中,使用impl块上的lifetime参数,并在方法签名中填充w的值'a的生命周期。 / p>

没有。生命周期参数'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

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

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