多重生命周期和移动:这里发生对借来的 `x` 的赋值
Multiple lifetimes and move: assignment to borrowed `x` occurs here
我有一个带有函数 next()
的结构(类似于迭代器,但不是迭代器)。此方法returns 修改后的下一个状态(保留原始状态)。所以: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();
}
}
错误是:
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
问题在这里:
impl<'a> B<'a> {
fn next(&self) -> B {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
您没有为 B
指定生命周期,next
的 return 类型。由于 Rust 的 lifetime elision rules,编译器推断您的意图是:
impl<'a> B<'a> {
fn next<'c>(&'c self) -> B<'c> {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
这意味着 return 值可能不会超过 self
。或者,换句话说,self
必须比 return 的 B
活得更长。考虑到函数体,这是一个 完全没有必要的要求 因为这些引用是相互独立的。它在这里引起了问题:
for _ in 0..5 {
b = b.next();
}
您正在覆盖借用检查器认为仍然通过调用 next()
借用的值。在 next
内部,我们知道不存在这种关系 – 生命周期注释不反映您实际所做的约束。
那么这里的生命周期是多少?
对 B
的引用的生命周期是无关的 - 每个都可以单独存在。因此,为了给调用者最大的灵活性,B
的生命周期应该不同于 next
.
[=67= 中对 self
的引用的生命周期]
但是,使用 next()
创建的每个 B
都持有对 相同 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
}
}
请注意——尽管这里 self
的 reference 有生命周期 'c
—— self
的类型是 B<'a>
,其中 'a
是里面 &u32
的生命周期。与 return 值相同。
但其实'c
是可以省略的。所以它真的和这个一样:
impl<'a> B<'a> {
fn next(&self) -> B<'a> {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
我有一个带有函数 next()
的结构(类似于迭代器,但不是迭代器)。此方法returns 修改后的下一个状态(保留原始状态)。所以: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();
}
}
错误是:
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
问题在这里:
impl<'a> B<'a> {
fn next(&self) -> B {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
您没有为 B
指定生命周期,next
的 return 类型。由于 Rust 的 lifetime elision rules,编译器推断您的意图是:
impl<'a> B<'a> {
fn next<'c>(&'c self) -> B<'c> {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}
这意味着 return 值可能不会超过 self
。或者,换句话说,self
必须比 return 的 B
活得更长。考虑到函数体,这是一个 完全没有必要的要求 因为这些引用是相互独立的。它在这里引起了问题:
for _ in 0..5 {
b = b.next();
}
您正在覆盖借用检查器认为仍然通过调用 next()
借用的值。在 next
内部,我们知道不存在这种关系 – 生命周期注释不反映您实际所做的约束。
那么这里的生命周期是多少?
对
[=67= 中对B
的引用的生命周期是无关的 - 每个都可以单独存在。因此,为了给调用者最大的灵活性,B
的生命周期应该不同于next
.self
的引用的生命周期]但是,使用
next()
创建的每个B
都持有对 相同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
}
}
请注意——尽管这里 self
的 reference 有生命周期 'c
—— self
的类型是 B<'a>
,其中 'a
是里面 &u32
的生命周期。与 return 值相同。
但其实'c
是可以省略的。所以它真的和这个一样:
impl<'a> B<'a> {
fn next(&self) -> B<'a> {
let mut new = self.clone();
new.0 = new.0 + 1;
new
}
}