If I have a slice, then I can get a subslice of it:
fn main() {
let backing_array = [0, 1, 2, 3, 4];
println!("Backing array: {:?}", backing_array);
let slice = &backing_array[1..];
let subslice = &slice[1..];
println!("Subslice: {:?}", subslice);
}
The subslice can even outlive its "parent", as long as the backing store outlives them both:
fn main() {
let backing_array = [0, 1, 2, 3, 4];
println!("Backing array: {:?}", backing_array);
let subslice = {
let slice = &backing_array[1..];
&slice[1..]
};
println!("Subslice: {:?}", subslice);
}
We can even do the same for a 2D array:
fn main() {
let backing_array = [[0, 1, 2, 3, 4]; 2];
println!("Backing array: {:?}", backing_array);
let subslices = {
let slices = backing_array
.iter()
.map(|arr| &arr[1..])
.collect::<Vec<&[u8]>>();
slices
.iter()
.map(|slice| &slice[1..])
.collect::<Vec<&[u8]>>()
};
println!("Subslices: {:?}", subslices);
}
And then make a custom Matrix wrapper, as long as we're careful with the lifetimes:
#[derive(Debug)]
struct Matrix<'a> {
lines: Vec<&'a [u8]>,
}
impl<'a> Matrix<'a> {
fn skip_cols<'b>(&self, cols: usize) -> Matrix<'b> where 'a: 'b {
Matrix {
lines: self.lines.iter().map(|line| &line[cols..]).collect()
}
}
}
fn main() {
let example_line = [0, 1, 2, 3, 4];
let backing_vec = [&example_line[..]; 2].to_vec();
let matrix = Matrix {
lines: backing_vec,
};
println!("Matrix: {:?}", matrix);
let subsubmatrix = {
let submatrix = matrix.skip_cols(1);
submatrix.skip_cols(1)
};
println!("Subsubmatrix: {:?}", subsubmatrix);
}
We can also make the slices mutable:
fn main() {
let mut backing_array = [0, 1, 2, 3, 4];
println!("Backing array: {:?}", backing_array);
let subslice = {
let slice = &mut backing_array[1..];
&mut slice[1..]
};
println!("Subslice: {:?}", subslice);
subslice[0] += 1;
println!("Subslice: {:?}", subslice);
}
However, making the 2D subslices mutable seems to break down completely (because subslices' lifetime must now be a subset of slices'):
fn main() {
let mut backing_array = [[0, 1, 2, 3, 4]; 2];
println!("Backing array: {:?}", backing_array);
let subslices = {
let mut slices = backing_array
.iter_mut()
.map(|arr| &mut arr[1..])
.collect::<Vec<&mut [u8]>>();
slices
.iter_mut()
.map(|slice| &mut slice[1..])
.collect::<Vec<&mut [u8]>>()
};
println!("Subslices: {:?}", subslices);
}
error[E0597]: `slices` does not live long enough
--> src/main.rs:10:9
|
10 | slices
| ^^^^^^ borrowed value does not live long enough
...
14 | };
| - `slices` dropped here while still borrowed
15 | println!("Subslices: {:?}", subslices);
16 | }
| - borrowed value needs to live until here
Am I misunderstanding something? Is this a borrowck bug?