循环中的可变借用
mutable borrows in a loop
我的代码:
struct Foo<'a> {
bytes: &'a mut [u8],
}
impl<'a> Foo<'a> {
fn bar<'b>(&'b mut self) {
self.bytes = &mut self.bytes[1..];
}
}
fn baz<'a, 'b>(foo: &'b mut Foo<'a>) {
println!("baz!");
for _ in 0..3 {
foo.bar();
}
}
这会导致以下错误回溯:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:12:27
|
12 | self.bytes = &mut self.bytes[1..];
| ^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
--> src/main.rs:11:12
|
11 | fn bar<'b>(&'b mut self) {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:12:27
|
12 | self.bytes = &mut self.bytes[1..];
| ^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
--> src/main.rs:10:6
|
10 | impl<'a> Foo<'a> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:12:22
|
12 | self.bytes = &mut self.bytes[1..];
| ^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0495`.
error: could not compile `playground` due to previous error
目标
我正在寻找更改 bar
/ baz
的函数签名以使其编译。我的理解是我需要在 'a
和 'b
上指定生命周期界限并且它会起作用,但是我在 [=33= 中的 'b: 'a
和 'a: 'b
得到不同的错误] 函数。
我还查看了大约 10 个其他“循环中的可变借用”问题,但我对答案的理解不够好,无法将它们应用到我的问题中,所以即使这是重复的,我也会很感激与这个玩具示例具体相关的答案。
感谢任何帮助!
这里的问题是通过 'b
发生借用。 ('b
和 'a
是不相交的)。编译器希望您保证引用 'b
需要至少与 'a
一样长。因此,我们应该寻找一种在(重新)借用切片时不涉及 'b
的方法,因为 'b
被认为仅在函数调用期间有效。调用没有 return
或“传出”生命周期。
可以使用std::mem::*
函数实现this
@vikram2784 的解决方案有效,但可以通过仅替换 bytes
而不是整个 Foo
:
来更简洁地表达
impl<'a> Foo<'a> {
fn bar(&mut self) {
let tmp = &mut [][..];
let bytes = std::mem::replace(&mut self.bytes, tmp);
self.bytes = &mut bytes[1..];
}
}
如果 Foo
包含一些没有明显默认值的附加字段,此模式也更易于使用。
关于这种解决方案需要注意的一点是:如果 bytes[1..]
崩溃,空的临时文件将留在原地。在这里,我能想到的恐慌的唯一原因就是bytes
是空的,所以没关系,但根据情况,你可能会被它咬到。
我的代码:
struct Foo<'a> {
bytes: &'a mut [u8],
}
impl<'a> Foo<'a> {
fn bar<'b>(&'b mut self) {
self.bytes = &mut self.bytes[1..];
}
}
fn baz<'a, 'b>(foo: &'b mut Foo<'a>) {
println!("baz!");
for _ in 0..3 {
foo.bar();
}
}
这会导致以下错误回溯:
Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:12:27
|
12 | self.bytes = &mut self.bytes[1..];
| ^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'b` as defined here...
--> src/main.rs:11:12
|
11 | fn bar<'b>(&'b mut self) {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:12:27
|
12 | self.bytes = &mut self.bytes[1..];
| ^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
--> src/main.rs:10:6
|
10 | impl<'a> Foo<'a> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:12:22
|
12 | self.bytes = &mut self.bytes[1..];
| ^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0495`.
error: could not compile `playground` due to previous error
目标
我正在寻找更改 bar
/ baz
的函数签名以使其编译。我的理解是我需要在 'a
和 'b
上指定生命周期界限并且它会起作用,但是我在 [=33= 中的 'b: 'a
和 'a: 'b
得到不同的错误] 函数。
我还查看了大约 10 个其他“循环中的可变借用”问题,但我对答案的理解不够好,无法将它们应用到我的问题中,所以即使这是重复的,我也会很感激与这个玩具示例具体相关的答案。
感谢任何帮助!
这里的问题是通过 'b
发生借用。 ('b
和 'a
是不相交的)。编译器希望您保证引用 'b
需要至少与 'a
一样长。因此,我们应该寻找一种在(重新)借用切片时不涉及 'b
的方法,因为 'b
被认为仅在函数调用期间有效。调用没有 return
或“传出”生命周期。
可以使用std::mem::*
函数实现this
@vikram2784 的解决方案有效,但可以通过仅替换 bytes
而不是整个 Foo
:
impl<'a> Foo<'a> {
fn bar(&mut self) {
let tmp = &mut [][..];
let bytes = std::mem::replace(&mut self.bytes, tmp);
self.bytes = &mut bytes[1..];
}
}
如果 Foo
包含一些没有明显默认值的附加字段,此模式也更易于使用。
关于这种解决方案需要注意的一点是:如果 bytes[1..]
崩溃,空的临时文件将留在原地。在这里,我能想到的恐慌的唯一原因就是bytes
是空的,所以没关系,但根据情况,你可能会被它咬到。