Cec*_*ile 4 reference lifetime rust borrowing
我有一个带有函数的结构next()(类似于迭代器但不是迭代器).此方法返回修改后的下一个状态(保留原始状态).所以:fn next(&A) -> A.
我从一个简单的结构开始,我不需要生命周期(示例中的结构A),我扩展它以添加对新结构(结构B)的引用.
问题是我现在需要指定我的结构的生命周期,并且由于某种原因我的方法next()拒绝再工作了.
我怀疑每次迭代的新结构的生命周期都限于创建它的范围,我不能将它移到这个范围之外.
是否可以保留我的next()方法的行为?
#[derive(Clone)]
struct A(u32);
#[derive(Clone)]
struct B<'a>(u32, &'a u32);
impl A {
fn next(&self) -> A {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
impl<'a> B<'a> {
fn next(&self) -> B {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
fn main() {
let mut a = A(0);
for _ in 0..5 {
a = a.next();
}
let x = 0;
let mut b = B(0, &x);
for _ in 0..5 {
b = b.next();
}
}
Run Code Online (Sandbox Code Playgroud)
错误是:
error[E0506]: cannot assign to `b` because it is borrowed
--> src/main.rs:31:9
|
31 | b = b.next();
| ^^^^-^^^^^^^
| | |
| | borrow of `b` occurs here
| assignment to borrowed `b` occurs here
Run Code Online (Sandbox Code Playgroud)
问题出在这里:
impl<'a> B<'a> {
fn next(&self) -> B {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
Run Code Online (Sandbox Code Playgroud)
您没有为B返回类型指定生命周期next.由于Rust的生命周期省略规则,编译器推断出您的意图:
impl<'a> B<'a> {
fn next<'c>(&'c self) -> B<'c> {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
Run Code Online (Sandbox Code Playgroud)
这意味着返回值可能不会超过self.或者,换句话说,self必须比B返回的时间更长寿.鉴于函数的主体,这是一个完全不必要的要求,因为这些引用是相互独立的.这会导致一个问题:
for _ in 0..5 {
b = b.next();
}
Run Code Online (Sandbox Code Playgroud)
您正在覆盖借用检查员认为仍然通过呼叫借入的值next().在内部next我们知道没有这样的关系 - 终身注释并不反映你实际做的事情的限制.
那么这里的生命界限是什么?
引用的生命周期B是不相关的 - 每个都可以不存在另一个.因此,给予最大的灵活性,以呼叫者的寿命B应该从参考的寿命不同self在next.
然而,每个B所创建的与next()保持于参考相同的 u32如由保持self.因此,您为每个参数提供的生命周期参数B必须相同.
使用明确命名的生命周期,这是结合这两件事的结果:
impl<'a> B<'a> {
fn next<'c>(&'c self) -> B<'a> {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
Run Code Online (Sandbox Code Playgroud)
需要注意的是-即使基准来self这里具有生命周期'c-类型的self就是B<'a>,这里'a是寿命&u32内.与返回值一样.
但实际上,'c可以省略.所以它真的和这个一样:
impl<'a> B<'a> {
fn next(&self) -> B<'a> {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |