こう書くと、
fn main() { let mut a = [1, 2, 3, 4, 5]; let x = &mut a[3..a.len()]; println!("{:?}", x); }
こう怒られる。
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable --> src/main.rs:3:23 | 3 | let x = &mut a[3..a.len()]; | -----^------- | | | | | immutable borrow occurs here | mutable borrow occurs here | mutable borrow later used here
こうなら良い。
fn main() { let mut a = [1, 2, 3, 4, 5]; let n = a.len(); let x = &mut a[3..n]; println!("{:?}", x); }
3..a.len()
を評価してから a
の可変参照を取るならなんの問題もないような気もするのだが、実際このコードは、
use std::ops::IndexMut; fn main() { let mut a = [1, 2, 3, 4, 5]; let x = a.index_mut(3..a.len()); println!("{:?}", x); }
と同値であり、 &mut a
も a.len()
も fn index_mut<'a>(&'a mut self, index: Side) -> &'a mut Self::Output
の引数となる。第1引数で可変参照を渡そうとしているのに第2引数で不変参照を用いているので怒られる。
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable --> src/main.rs:5:28 | 5 | let x = a.index_mut(3..a.len()); | - --------- ^ immutable borrow occurs here | | | | | mutable borrow later used by call | mutable borrow occurs here
まあそもそも、このサンプルのように末尾まで取りたいのなら、以下のように書くのが正しい。
fn main() { let mut a = [1, 2, 3, 4, 5]; let x = &mut a[3..]; println!("{:?}", x); }
a.len() - 1
まで取りたいのなら分けて書かないと駄目なのかな。