链接 self 的生命周期和方法中的引用
Linking the lifetimes of self and a reference in method
#[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
被编译器分配了不同的生命周期,这是 f
(Foo
对象)的生命周期。如果我在 main
函数中切换 w
和 f
的绑定顺序,这将导致错误。
我想知道如果我在 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
选择了一个与 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
正是因为 v
强加的 'a
生命周期与 w
的较短生命周期不兼容。
在第二个示例中,通过强制 self
的生命周期也为 'a
,您也将可变借用绑定到生命周期 'a
,因此当生命周期 'a
的所有项目超出范围时,借用结束,即 v
和 w
.
#[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
被编译器分配了不同的生命周期,这是 f
(Foo
对象)的生命周期。如果我在 main
函数中切换 w
和 f
的绑定顺序,这将导致错误。
我想知道如果我在 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 ofw
is filled in for'a
in the method signature.
没有。生命周期参数 '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
正是因为 v
强加的 'a
生命周期与 w
的较短生命周期不兼容。
在第二个示例中,通过强制 self
的生命周期也为 'a
,您也将可变借用绑定到生命周期 'a
,因此当生命周期 'a
的所有项目超出范围时,借用结束,即 v
和 w
.