我已经:
#[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
的值时,结构声明上的泛型lifetime参数'a
将用v
的值的lifetime填充。这意味着生成的Foo
对象的生存期不能长于此'a
对象的生存期,或者v
的值必须至少与Foo
对象的生存期一样长。在调用方法
set
时,使用impl
块上的lifetime参数,并在方法签名中为w
填充'a
值的lifetime。编译器为&mut self
分配了不同的生存期,即f
对象的生存期。如果我在Foo
函数中切换w
和f
绑定的顺序,这将导致错误。我想知道如果我用与
main
方法中的&mut self
相同的生存期参数'a
注释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
与上面的例子相反,
set
在第二次打印时仍然被认为是可变借用的!被调用,因此它不能作为不可变的同时借用。怎么会这样?
在第一个例子中,编译器通过不省略lifetime注释为我填写了一个
f
。这是根据终生逃避的规则发生的。然而,在第二个示例中,通过显式地将其设置为&mut self
,我将'a
的值和f
的值的生命周期联系起来。是否被认为是自己借的?
如果是的话,借款的范围是什么?是最小寿命(寿命
w
,寿命f
)->寿命f
?我想我还没有完全理解函数调用中的
w
引用。我的意思是,函数返回,但是f
仍然被认为是借用的。我试着完全理解人生。我主要是在我对概念的理解上寻找纠正性反馈。我非常感谢你的每一点建议和进一步的澄清。
最佳答案
在调用方法set
时,使用impl块上的lifetime参数,并在方法签名中为w
填写值'a
的lifetime。
不可以。lifetime参数'a
的值在创建Foo
结构时是固定的,并且永远不会更改,因为它是其类型的一部分。
在您的例子中,编译器实际上为'a
选择了一个与v
和w
的生存期都兼容的值。如果这不可能,它将失败,例如在本例中:
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
的所有项都超出范围(即v
和w
)时,借阅结束。关于rust - 将自我和引用中的生命周期联系起来,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56308715/