“no method found for type T in the current scope”

2019-07-29 23:17发布

问题:

I am trying to make adapters around 2 different types that do the same job and I cannot rewrite the two types.

X has a method which consumes self so a run-time polymorphic wrapper is not applicable. The only option is a static generic approach.

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

The compiler fails with:

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

回答1:

The problem is here:

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

This says

give me any possible type, and I will call the uf method on it

That's clearly nonsense, as you could pass in a String or bool or HashMap or a File or a .... (you get the point).

There's no method uf that applies to every type, so the compiler tells you so. As you discovered, you have to provide a bound on the generic type with one or more traits. Methods and associated functions from those traits will be usable inside the method.

Also note that the Rust style is snake_case; the function should be called use_adapted.



回答2:

I was able to figure it out; the wrapper struct is not needed. The right way is a generic trait. I also missed the type scope for the generic type variable.

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


标签: rust adapter