具有特征的通用API

时间:2019-01-13 03:32:17

标签: rust traits

我正在尝试对API进行泛化/解耦,以便可以使用满足Trait的替代结构。在有关嵌套特征的语法上苦苦挣扎。这是我正在尝试做的精简示例。请注意,在真实的情况下,有多个子特征,这可能会引起一个后续问题:“如果我走对了路,如何减少冗长”。

pub mod general {
    /// A trait to make the API generic
    pub trait MyTrait<A: PartialEq> {
        // type A: Partial
        fn val(self) -> A;
    }

    /// Part of the generic API
    pub struct Data<A: PartialEq, T: MyTrait<A>> {
        mys: T
    }

    /// Another part of the generic API
    fn doit<A: PartialEq>(s: impl MyTrait<A>) -> impl MyTrait {
        s
    }
}

pub mod specific {
    /// Api-specific substruct
    #[derive(PartialEq)]
    pub struct Aval {
        val: u32
    }

    /// My top-level custom struct
    pub struct MyS {
        val: Aval
    }
}

impl<A: PartialEq> crate::general::MyTrait<A> for crate::specific::MyS {
    fn val(self) -> crate::specific::Aval {
        self.val
    }
}

/// Example of how we'd use this
fn main() {
    let mys = crate::specific::MyS{ val: crate::specific::Aval{ val: 0 } };
    let S = crate::general::Data{mys};
    crate::general::doit(mys);  // Eg pretend we cloned or didn't create S.
}

Playground

在此特定示例中,我们有一个Chicken + egg:error[E0392]: parameter `A` is never used数据结构上的错误。如果我们删除A:error[E0412]: cannot find type `A` in this scope

我怀疑这是与关联类型有关的语法问题。

1 个答案:

答案 0 :(得分:1)

只需从您的struct中删除绑定的特征即可。

struct Data<T> {
    mys: T
}

您仍然可以为Data<T>添加方法和特征实现,这些方法和特征实现需要在T上有更具体的界限,但是您不需要它们来定义Data<T>的布局,因此您不应该不能在此处指定它们(在这种情况下,除非添加指向PhantomData的{​​{1}}成员,否则您就无法指定它们。)

您的代码还有许多其他错误,但是我相信您会发现它们。如果您再次遇到困难,请随时发表评论。