I am trying to go thru the vector 2x to calc distances between all ships in the simulation. Clippy told me to iterate via for i in &ships and not to use i in 0..ships.len(). So now I have this error and it makes sense but I am at a loss on how to fix it. As I understand only 1 iterator needs to be mut, the other just reads values.
Code in question is here:
// now calculate distance to shortest target
for i in &mut ships {
for j in &ships {
if i.name != j.name {
let d = i.location.calc_distance(j.location);
if d < i.s_target {
i.s_target = d;
}
println!("{} targets {} = {}",
i.name, j.name, d);
}
}
}
This may be a false positive from Clippy, since it saw one loop could be replaced but couldn't tell the other loop was also using the same variable. The indexing method works.
The other thing you can do is use Cell. This is easiest if your type implements Copy.
let ship_cells = Cell::from_mut(&mut ships).as_slice_of_cells();
for ic in ship_cells {
for jc in ship_cells {
let i = ic.get();
let j = jc.get();
if i.name != j.name {
let d = i.location.calc_distance(j.location);
if d < i.s_target {
i.s_target = d;
}
println!("{} targets {} = {}",
i.name, j.name, d);
}
ic.set(i);
// jc.set(j);
}
}
You may also consider improving your algorithm if the order of the prints doesn't matter:
for split in 0..ships.len() - 1 {
let end = ships[split..];
let (i, rest) = end.split_first_mut().unwrap();
for j in rest {
let d = i.location.calc_distance(j.location);
if d < i.s_target {
i.s_target = d;
}
println!("{} targets {} = {}", i.name, j.name, d);
let d = j.location.calc_distance(i.location);
if d < j.s_target {
j.s_target = d;
}
println!("{} targets {} = {}", j.name, i.name, d);
}
}