【问题标题】:How to specify a generic argument for a type that implements trait Fn when the args are not constrained?当参数不受约束时,如何为实现特征 Fn 的类型指定泛型参数?
【发布时间】:2020-03-09 01:22:14
【问题描述】:

我正在尝试使用“地图”概念来实现特征。我想出了以下最小示例:

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

我收到错误the type parameterTis not constrained by the impl trait, self type, or predicates

F 是将值S 映射到其他值的函数时,我如何为我的ValueMap 结构实现Value 特征?

备注:我在 Value 上使用关联类型时没有这个问题。但是这些概念对我来说还是有点模糊。

【问题讨论】:

    标签: generics rust


    【解决方案1】:

    错误消息#0E207 的详细信息如下:

    impl 的任何类型参数或生命周期参数必须至少满足 以下条件之一:

    • 它出现在impl的实现类型中,例如impl&lt;T&gt; Foo&lt;T&gt;
    • 对于特征impl,它出现在已实现的特征中,例如impl&lt;T&gt; SomeTrait&lt;T&gt; for Foo
    • 它被绑定为关联类型,例如impl&lt;T, U&gt; SomeTrait for T where T: AnotherTrait&lt;AssocType=U&gt;

    这些都不适用于您的 T。所以目前不支持你正在做的事情。

    感觉很老套,但我能够通过向 ValueMap 添加额外的类型参数来实现它,并由幻像数据成员支持。这样每个类型都确实出现在实现类型中,并且满足要求。

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-07
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多