I have a struct which contains a Vec
of instances of another base class of struct. I am trying to iterate over the Vec
and spawn threads which each run a single impl fn
from the base struct. Nothing needs mutable access at any time after the iteration of thread spawning begins; just some basic math returning an f64
(based on values in a HashMap
using keys stored in a fixed Vec
in each base struct).
I am running into lifetime issues which I don't fully understand and which the compiler error messages (for once) don't help with.
Here is a stripped down version of what I want to implement (with some annotation of the errors encountered):
struct BaseStruct {
non_copy_field: Vec<&'static str>, // BaseStruct has vector members (thus can't implement Copy).
}
impl BaseStruct {
fn target_function(&self, value_dict: &HashMap<&'static str, f64>) -> f64 {
// Does some calculations, returns the result.
// Uses self.non_copy_field to get values from value_dict.
0.0
}
}
struct StructSet {
values: HashMap<&'static str, f64>, // This will be set prior to passing to base_struct.target_function().
all_structs: Vec<BaseStruct>, // Vector to be iterated over.
}
impl StructSet {
fn parallel_calculation(&self) -> f64 {
let mut result = 0.0;
let handles: Vec<_> = self.all_structs.iter().map(|base_struct| {
// Complains about lifetime here ^^^^^ or ^ here if I switch to &base_struct
thread::spawn(move || {
base_struct.target_function(&self.values)
})
}).collect();
for process in handles.iter() {
result += process.join().unwrap();
};
// Shouldn't all base_structs from self.all_structs.iter() be processed by this point?
result
} // Why does it say "...so that reference does not outlive borrowed content" here?
}
I have been trying various combinations of RwLock
/Arc
/Mutex
wrapping the contents of the fields of StructSet
to attempt to gain thread-safe, read-only access to each of the elements iterated/passed, but nothing seems to work. I'm looking to keep the codebase light, but I guess I'd consider rayon or similar as I'll need to follow this same process multiple places in the full module.
Can anyone point me in the correct direction?