2016-08-07 38 views
1

Ich versuche, Adapter um zwei verschiedene Typen herzustellen, die den gleichen Job machen, und ich kann die beiden Typen nicht umschreiben."keine Methode für Typ T im aktuellen Bereich gefunden" beim Umhüllen eines Typs

X hat eine Methode, die self verbraucht, so dass eine polymorphe Laufzeitumgebung nicht anwendbar ist. Die einzige Option ist ein statischer generischer Ansatz.

struct X {} 

impl X { 
    fn f(self, n: i32) { 
     println!("n = {}", n); 
    } 
    fn new() -> X { 
     X {} 
    } 
} 

struct AdapterX { 
    x: X 
} 

impl AdapterX { 
    fn uf(self, n: i32) { 
     self.x.f(n) 
    } 
    fn new(x: X) -> AdapterX { 
     AdapterX { x: x } 
    } 
} 

fn useAdapted<T>(a: T) { 
    a.uf(10) 
} 

fn main() { 
    let x = X::new(); 
    useAdapted::<AdapterX>(AdapterX::new(x)); 
} 

Der Compiler schlägt fehl mit:

error: no method named `uf` found for type `T` in the current scope 
    a.uf(10) 
     ^~ 

Antwort

0

Ich war in der Lage, es herauszufinden; Die Wrapper-Struktur wird nicht benötigt. Der richtige Weg ist ein generisches Merkmal. Ich habe auch den Typbereich für die generische Typvariable verpasst.

struct X {} 

impl X { 
    fn f(self, n: i32) { 
     println!("n = {}", n); 
    } 
    fn new() -> X { 
     X {} 
    } 
} 

trait Adapter<T> { 
    fn uf(self, n: i32); 
} 

impl Adapter<X> for X { 
    fn uf(self, n: i32) { 
     self.f(n) 
    } 
} 

struct Y {} 

impl Y { 
    fn g(self, n: f32) { 
     println!("m = {}", n); 
    } 
    fn new() -> Y { 
     Y {} 
    } 
} 

impl Adapter<Y> for Y { 
    fn uf(self, n: i32) { 
     self.g(n as f32) 
    } 
} 

fn use_adapted<A, T: Adapter<A>>(a: T) { 
    a.uf(10) 
} 

fn main() { 
    use_adapted(X::new()); 
    use_adapted(Y::new()); 
} 
3

Das Problem dabei ist:

fn useAdapted<T>(a: T) { 
    a.uf(10) 
} 

Dies sagt

geben Sie mir jeden möglichen Typen, und ich werde die uf Methode auf es

nennen Das ist eindeutig Unsinn, wie Sie könnten in eine String oder bool oder HashMap oder eine File oder a .... (Sie bekommen den Punkt) übergeben.

Es gibt keine Methode uf, die gilt für jeder Typ, so der Compiler teilt Ihnen dies mit. Wie Sie festgestellt haben, müssen Sie einen gebundenen auf dem generischen Typ mit einem oder mehreren Merkmalen bereitstellen. Methoden und zugehörige Funktionen aus diesen Merkmalen können innerhalb der Methode verwendet werden.

Beachten Sie auch, dass der Rust-Stil snake_case ist; Die Funktion sollte use_adapted heißen.

+0

Wie setzen Sie diese Grenze? – mjwrazor

+0

@mjwrazor Wenn Sie ein wenig nach unten scrollen, sehen Sie, dass [OP ein Merkmal einführt und es als Grenze verwendet] (http://stackoverflow.com/a/38813039/155423). – Shepmaster