2015-07-02 4 views
7

Neu in Rust hier, Entschuldigung für meine Naivität.Methoden unter Strukturen geteilt

Ich möchte einige Wahrscheinlichkeitsverteilungen definieren, die offensichtlich unterschiedliche Parameter haben. Aber die "Schnittstelle" (wie ich sie in Java kenne) sollte die gleiche sein. Auf der grundlegendsten Ebene sollte jede Verteilung eine sample und eine sample_many Methode haben. So implementieren ich ein Merkmal:

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

Dann wird eine spezifische Verteilung erstellt werden kann:

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() 
    } 
} 

Mein Problem ist, mit dem sample_many Verfahren, speziell. Diese Methode wird unabhängig von der Art der Verteilung, z.

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 Kopieren der Methode hier ist ziemlich redundant. Gibt es einen Weg dahin?

+0

@ker Meine Absicht nicht übersetzbar Beispiel erstellen war überschrieben werden, aber nur ein Beispiel für eine verallgemeinerungsfähige Ausgabe, also das Weglassen 'sample' in' Gaussian' – jayelm

+0

Rost hat die ' nicht implementiert!() 'Makro für solche Situationen. Dein Code wird kompiliert, tut aber nichts nützliches. Sie können dies in http://is.gd/WwsBW2 sehen –

+0

Für Code, der sehr ähnlich ist, macht manchmal eine Implementierung Makro sinnvoll. Obwohl ich denke, dass die Standardimplementierung von @ ker hier am besten geeignet ist. (siehe Makrofrage: http://stackoverflow.com/questions/31082179/implementing-a-tit-for-a-trait) – jocull

Antwort

8

Sie können eine Standardimplementierung für jede Funktion in der Merkmalsdefinition erstellen. Es kann immer noch durch einen Implementierer

pub trait ERP<T> { 
    fn sample(&self) -> T; 
    fn sample_many(&self, i: isize) -> Vec<T> { 
     (0..i).map(|_| self.sample()).collect() 
    } 
} 
+0

Das war zu einfach, danke! – jayelm