以下示例说明了我正在尝试做的事情:
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());
}
}
以上不会编译。问题是,我无法在第一个 for_each 的关闭中访问 &self.children。我确实明白,为什么借用检查器不允许这样做,所以我的问题是,是否有办法让它在很少改变的情况下工作。到目前为止我找到的解决方案并不令人满意。一种解决方案是在 Parent::calculate 距离的开头克隆孩子并在闭包内使用它(这会添加不必要的克隆)。另一种解决方案是像这样提取 Child 的 value 字段:
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();
}
}
}
虽然这会很有效,但它完全弄乱了我的真实代码,并且价值在概念上真的属于 Child。我对 rust 比较陌生,只是问自己是否有任何好的方法可以做到这一点。据我了解,需要一种方法来告诉编译器,我只更改并行迭代器中的距离字段,而值字段保持不变。也许这是一个使用不安全的地方?无论如何,如果你能提示我正确的方向,我将非常感激,或者至少确认我的代码真的必须变得更加混乱才能使它工作:)