I am trying to simulate and transform data with multithreading, while leaving to user what kind of transformation to use, as long as it implements my Transformation
trait.
I understand broadly why complier doesn't like to use raw Transformation
in .map()
method, but I wanted to know the best way to approach this problem in Rust.
I am using rayon
here but any other suggestion will be also appreciated.
use rayon::prelude::*;
pub trait Transformation {
fn result(&self, input: &f64) -> f64;
}
pub struct Division {
pub by: f64
}
impl Transformation for Division {
fn result(&self, input: &f64) -> f64 {
input / self.by
}
}
fn simulate_and_transform(paths_num: &usize, trans: &dyn Transformation) -> Vec<f64> {
(0..*paths_num)
.into_par_iter()
.map(|_| trans.result(&rand::random::<f64>()))
.collect()
}
fn main() {
let div = Division {by: 2.0};
let paths = 100;
let sims = simulate_and_transform(&paths, &div);
println!("Samples: {}, {}, {}", sims[3], sims[56], sims[99]);
}
CodePudding user response:
There is only a simple problem here: you haven't required that the Transformation
is safe to use from multiple threads. That is expressed using the Sync
trait. You can either require it for all implementors of the trait:
pub trait Transformation: Sync {
or you can require it when it's used:
fn simulate_and_transform(paths_num: &usize, trans: &(dyn Transformation Sync)) -> Vec<f64> {
Either of these changes will allow your program to compile.