Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Methods shared among structs

New to Rust here, apologies for my naiveté.

I want to define some probability distributions, which obviously have differing parameters. But the "interface" (as I know it in Java) should be the same. At the most basic level each distribution should have a sample and a sample_many method. So I implement a trait:

pub trait ERP<T> {
    fn sample(&self) -> T;
    fn sample_many(&self, i: isize) -> Vec<T>;
}

Then a specific distribution can be created:

pub struct Bernoulli {
    pub p: f64
}

impl ERP<bool> for Bernoulli {
    fn sample(&self) -> bool {
        rand::random::<f64>() < self.p
    }

    fn sample_many(&self, i: isize) -> Vec<bool> {
        (0..i).map(|_| self.sample()).collect()
    }
}

My issue is with the sample_many method, specifically. This method will be the same code regardless of the kind of distribution, e.g.

pub struct Gaussian {
    pub mu: f64,
    pub sigma: f64
}

impl ERP<f64> for Gaussian {
    fn sample(&self) -> f64 {
        // Code unique to each distribution
    }

    fn sample_many(&self, i: isize) -> Vec<f64> {
        (0..i).map(|_| self.sample()).collect() // Code reuse??
    }
}

So copying the method here is pretty redundant. Is there a way around this?

like image 956
jayelm Avatar asked Jul 02 '15 13:07

jayelm


1 Answers

You can create a default implementation for any function in the trait definition. It can still be overwritten by an implementor

pub trait ERP<T> {
    fn sample(&self) -> T;
    fn sample_many(&self, i: isize) -> Vec<T> {
        (0..i).map(|_| self.sample()).collect()
    }
}
like image 66
oli_obk Avatar answered Oct 28 '22 20:10

oli_obk