the following example illustrates what i am trying to do:
use rayon::prelude::*;
struct Parent {
children: Vec<Child>,
}
struct Child {
value: f64,
index: usize,
//will keep the distances to other children in the children vactor of parent
distances: Vec<f64>,
}
impl Parent {
fn calculate_distances(&mut self) {
self.children
.par_iter_mut()
.for_each(|x| x.calculate_distances(&self.children));
}
}
impl Child {
fn calculate_distances(&mut self, children: &[Child]) {
children
.iter()
.enumerate()
.for_each(|(i, x)| self.distances[i] = (self.value - x.value).abs());
}
}
The above won't compile. The problem is, that i can't access &self.children in the closure of the first for_each. I do understand, why the borrow checker does not allow that, so my question is, if there is a way to make it work with little changes. The solutions i found so far are not really satisfying. One solution would be to just clone children at the beginning of Parent::calculate distances and use that inside the closure(which adds an unnecessary clone). The other solution would be to extract the value field of Child like that:
use rayon::prelude::*;
struct Parent {
children: Vec<Child>,
values: Vec<f64>
}
struct Child {
index: usize,
//will keep the distances to other children in the children vactor of parent
distances: Vec<f64>,
}
impl Parent {
fn calculate_distances(&mut self) {
let values = &self.values;
self.children
.par_iter_mut()
.for_each(|x| x.calculate_distances(values));
}
}
impl Child {
fn calculate_distances(&mut self, values: &[f64]) {
for i in 0..values.len(){
self.distances[i]= (values[self.index]-values[i]).abs();
}
}
}
while this would be efficient it totally messes up my real code, and value conceptually just really belongs to Child. I am relatively new to rust, and just asked myself if there is any nice way of doing this. As far as i understand there would need to be a way to tell the compiler, that i only change the distances field in the parallel iterator, while the value field stays constant. Maybe this is a place to use unsafe? Anyways, i would really appreciate if you could hint me in the right direction, or at least confirm that my code really has to become so much messier to make it work:)