借用检查器:不能作为不可变的借用,因为它也作为可变的借用。

3
我遇到了借用检查器无法“释放”可变借用的问题。
代码如下:
let mut data = (1..=100).collect::<Vec<_>>();
let mut c = Canvas::new(10, 10, &mut data);


c.iter_rows_mut(4..7);
c.iter_rows(4..7).collect::<Vec<_>>();

它在抱怨:

error[E0502]: cannot borrow `c` as immutable because it is also borrowed as mutable
  --> src/lib.rs:59:9
   |
57 |         c.iter_rows_mut(4..7);
   |         - mutable borrow occurs here
58 | 
59 |         c.iter_rows(4..7).collect::<Vec<_>>();
   |         ^
   |         |
   |         immutable borrow occurs here
   |         mutable borrow later used here

error: aborting due to previous error

如果我正在处理与可变调用相关的引用,我可以理解这个问题,但似乎并非如此。
完整代码的 Rust Playground:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=de4143ddf57cc8a97e7a884bbe13dfa4
1个回答

5
这里的问题出在生命周期注解上。您一直使用相同的生命周期 'd,因此在 c.iter_rows_mut 中的可变借用必须持续整个 c 的生命周期。
要解决这个问题,请在 iter_rowsiter_rows_mut 中使用不同的生命周期。它将被隐式地绑定为不超过 'd,但会允许更多的灵活性。
完全明确的签名应该是:
fn iter_rows<'a>(&'a self, vertical_range: Range<usize>) -> impl Iterator<Item=(usize, &'a [T])> + 'a

并且

fn iter_rows_mut<'a>(&'a mut self, vertical_range: Range<usize>) -> impl Iterator<Item=(usize, &'a mut [T])> + 'a {

感谢终身延长,我们不需要任何这些生命周期。 输出类型中的所有生命周期将隐式与“& self”(或“& mut self”)上的生命周期相同。
fn iter_rows(&self, vertical_range: Range<usize>) -> impl Iterator<Item=(usize, &[T])>

fn iter_rows_mut(&mut self, vertical_range: Range<usize>) -> impl Iterator<Item=(usize, &mut [T])>

(游乐场)

附:这些函数中的into_iter调用并不是必要的: chunks_exact已经产生了一个迭代器。Clippy对此发出了警告。


非常好的、详尽的回答。谢谢! - Dustin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接