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

Dus*_*tin 3 rust

我遇到借用检查器无法“释放”可变借用的问题。

我有:

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<_>>();
Run Code Online (Sandbox Code Playgroud)

它在抱怨:

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
Run Code Online (Sandbox Code Playgroud)

如果我传递与可变调用相关的引用,我可以理解这个问题,但情况似乎并非如此。

Rust Playground 包含完整代码:https://play.rust-lang.org/? version=stable&mode=debug&edition=2018&gist=de4143ddf57cc8a97e7a884bbe13dfa4

SCa*_*lla 5

这里的问题在于生命周期注释。您'd始终使用相同的生命周期,因此可变借用c.iter_rows_mut必须持续 的整个生命周期c

iter_rows要解决此问题,请在和中使用不同的生命周期iter_rows_mut。它会被隐式地限制为不长于'd,但它会提供更大的灵活性。

完全显式的签名应该是

fn iter_rows<'a>(&'a self, vertical_range: Range<usize>) -> impl Iterator<Item=(usize, &'a [T])> + 'a
Run Code Online (Sandbox Code Playgroud)

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

不过,由于生命周期省略,我们不需要任何这些生命周期。&self输出类型中的所有生命周期将隐式与(或)上的生命周期相同&mut self

fn iter_rows(&self, vertical_range: Range<usize>) -> impl Iterator<Item=(usize, &[T])>
Run Code Online (Sandbox Code Playgroud)
fn iter_rows_mut(&mut self, vertical_range: Range<usize>) -> impl Iterator<Item=(usize, &mut [T])>
Run Code Online (Sandbox Code Playgroud)

(操场)

PSinto_iter每个函数中的调用都是不必要的:chunks_exact已经生成了一个迭代器。Clippy 对此发出警告。