简体   繁体   中英

Working around the lack of associated method on parametric traits?

Note: I am aware of Rust invoke trait method on generic type parameter , unfortunately the work around described there does not seem to work for me, probably because my trait is parametric.


I tried to implement a parameterized trait with an associated method:

trait Parameterized<T> {
    fn static_call<'a>(t: &'a T) -> &'a T;
}

struct Foo;

impl Parameterized<u32> for Foo {
    fn static_call<'a>(t: &'a u32) -> &'a u32 { t }
}

The goal of course is afterward to use such method:

struct PP<T, P: Parameterized<T>> {
    p: P
}

impl<T, P> PP<T, P>
    where P: Parameterized<T>
{
    fn call_it<'a>(t: &'a T) -> &'a T {
        P::static_call(t)
    }
}

But unfortunately things go down hill from here. The syntax here presented is the most obvious, however associated methods are not implemented yet and therefore the compiler rejects the code (with a baffling error message):

error: failed to resolve. Use of undeclared type or module `P`
              P::static_call(t)
              ^~~~~~~~~~~~~~

Okay, fine, let's try the work-around described in the previous question then!

impl<T, P> PP<T, P>
    where P: Parameterized<T>
{
    fn call_it<'a>(t: &'a T) -> &'a T {
        Parameterized::<T>::static_call(t)
    }
}

which results in:

error: type annotations required: cannot resolve `_ : Parameterized<T>`
              Parameterized::<T>::static_call(t)
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

That's fair enough, as there are indeed no way for the compiler to infer that I meant the particular implementation of Parameterized<T> for P . Let's pick up the syntax used for associated types then:

impl<T, P> PP<T, P>
    where P: Parameterized<T>
{
    fn call_it<'a>(t: &'a T) -> &'a T {
        <P as Parameterized<T>>::static_call(t)
    }
}

Nope, not working either:

error: unexpected token: `<`
              <P as Parameterized<T>>::static_call(t)
              ^

So that is not the way to annotate then.

I am open to suggestions of work-arounds, beyond adding &self obviously.

The work-around with a dummy parameter to specify Self , given in your first link seems to work; adjusting to:

fn static_call<'a>(t: &'a T, _unused: Option<Self>) -> &'a T;

// ...

    Parameterized::static_call(t, None::<P>)

compiles fines for me.

(Incidentally this looks like a situation where associated types, trait Parameterized { type T; may be useful, but it doesn't resolve this problem and may be completely different from your real, non-reduced code.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM