What's the correct way to loop over 0 .. v.len() - 1 when the vector v might be empty?
Consider the following code, which prints all choices of 2 elements in a vector [5, 6, 7]:
fn main() {
let v: Vec<i32> = vec![5, 6, 7];
for i in 0 .. v.len() - 1 {
for j in i + 1 .. v.len() {
println!("{} {}", v[i], v[j]);
}
}
}
It prints
5 6
5 7
6 7
as expected.
Now, if we instead have
let v: Vec<i32> = vec![];
then the program panics due to overflow, which is also expected.
Q: How to fix it without changing the structure and the logic of the program, and without involving signed integers?
The following are some examples of the workarounds that I don't want:
Handling empty
vseparately (changes the logic). Overall, I don't want any checks thatvis empty, e.g. byif v.len() == 0 { 0 } else { v.len() - 1 }Changing the order of loops (changes the logic and the output):
for j in 0 .. v.len() { for i in 0 .. j {Shifting the indices (changes the logic):
for i in 1 .. v.len() { for j in i .. v.len() { // Now i is shifted by 1Using i32 (casts):
for i in 0 .. v.len() as i32 - 1 { for j in i + 1 .. v.len() as i32 { // cast i and j to usize
Overall, I hope that there is a clean way to handle 0 .. v.len() - 1 without any hacks.
Notice that, if
i == v.len()-1, nothing happens in the body of the outer loop, becausei+1..v.len()is an empty iterator. Therefore, the simplest way to avoid integer underflows is simply to remove the-1:produces
and if I replace
vwithVec::new(), you get no output, as expected.