我有 这段代码:
#[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
对象不能比这个生命周期更长,或者说v
的值必须至少和Foo
对象一样长。
在调用set
方法时,impl
块上的生命周期参数会被使用,并且w
值的生命周期会被填充为方法签名中的'a
参数。编译器会为&mut self
分配另一个生命周期,即f
(Foo
对象)的生命周期。如果我在main
函数中交换了w
和f
的绑定顺序,这将导致错误。
我想知道如果我给&mut self
引用注释相同的生命周期参数'a
,跟set
方法中的r
一样,会发生什么:
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
是否被认为是自身被借用了吗?
如果是这样,这种借用的范围是什么?是min(f
的生命周期,w
的生命周期) -> f
的生命周期吗?
我想我还没有完全理解函数调用中的&mut self
借用。我的意思是,函数返回了,但f
仍然被认为被借用了。
我正在努力理解生命周期。我主要寻求关于概念理解的纠正意见。我非常感谢每一点建议和进一步的解释。