简体   繁体   中英

How to specify a generic argument for a type that implements trait Fn when the args are not constrained?

I am trying to implement a trait using a "map" concept. I've came up with the following minimal example:

trait Value<T> {
    fn get(&self) -> T;
}
struct ValueMap<S, F> {
    s: S,
    f: F,
}
impl<T, U, S: Value<T>, F: Fn(T) -> U> Value<U> for ValueMap<S, F> {
    fn get(&self) -> U {
        (self.f)(self.s.get())
    }
}

I get the error the type parameter T is not constrained by the impl trait, self type, or predicates .

How may I implement the Value trait for my ValueMap struct when F is a function that maps the value S to something else?

Remarks: I don't have this issue when I use associated types on Value. But the concepts are still a bit blurry for me.

The details for error message #0E207 say that:

Any type parameter or lifetime parameter of an impl must meet at least one of the following criteria:

  • it appears in the implementing type of the impl , eg impl<T> Foo<T>
  • for a trait impl , it appears in the implemented trait, eg impl<T> SomeTrait<T> for Foo
  • it is bound as an associated type, eg impl<T, U> SomeTrait for T where T: AnotherTrait<AssocType=U>

None of these hold for your T . So what you're doing is currently not supported.

It feels hacky, but I was able to get this to work by adding additional type parameters to ValueMap, backed by phantom data members. This way each of the types does occur in the imlementing type, and the requirements are satisfied.

trait Value<T> {
    fn get(&self) -> T;
}

struct ValueMap<T, U, S, F>
where
    F: Fn(T) -> U,
{
    s: S,
    f: F,
    _t: std::marker::PhantomData<T>,
    _u: std::marker::PhantomData<U>,
}

impl<T, U, S, F> Value<U> for ValueMap<T, U, S, F>
where
    S: Value<T>,
    F: Fn(T) -> U,
{
    fn get(&self) -> U {
        (self.f)(self.s.get())
    }
}

Playground link

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