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 v
separately (changes the logic). Overall, I don't want any checks that v
is empty, e.g. by if 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 1
Using 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, because i+1..v.len()
is an empty iterator. Therefore, the simplest way to avoid integer underflows is simply to remove the -1
:
fn main() {
let v: Vec<i32> = vec![5, 6, 7];
for i in 0 .. v.len() {
for j in i + 1 .. v.len() {
println!("{} {}", v[i], v[j]);
}
}
}
produces
5 6
5 7
6 7
and if I replace v
with Vec::new()
, you get no output, as expected.