接收错误[E0276]:impl 比带有泛型的特征有更严格的要求

Afs*_*ani 4 rust

我试图定义一个特征来比较两个给定的参数并Result根据实现返回一个。它有两个泛型,但当我们实现它时它们可以是任何东西:

pub trait Assert<L: Any + Debug> {
    fn compare<R: Any + Debug>(self, target: R) -> AssertResult;
}
Run Code Online (Sandbox Code Playgroud)

现在,当我想实现 equal 时,我会这样做:

pub struct Equal<L> {
    expected: L,
}

impl<L> Equal<L> {
    pub fn new(expected: L) -> Equal<L> {
        Equal { expected: expected }
    }
}

impl<L: 'static + fmt::Debug> Assert<L> for Equal<L> {
    fn compare<R: PartialEq<L> + fmt::Debug>(self, target: R) -> AssertResult {
        if target == self.expected {
            Ok(())
        } else {
            Err(format!(
                "Expected {:?}, received {:?}",
                self.expected,
                target
            ))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

链接到游乐场

我希望能够接受任何事情LR但在实施中限制它们。我不确定这是否是正确的方法。

tre*_*tcl 7

该特征未使用Lin ,因此它没有任何作用;Assert<L>我会忽略它。如果没有这种复杂性,这就是您所写的:

pub trait Assert {
    fn compare<R: Any + Debug>(self, target: R) -> AssertResult;
}
Run Code Online (Sandbox Code Playgroud)

这是一个约定,“当一个类型实现 时Assert,它应提供一个可以使用任何实现和compare的类型的参数来调用的方法。”AnyDebug

impl<L: 'static + fmt::Debug> Assert for Equal<L> {
Run Code Online (Sandbox Code Playgroud)

这是一个协议,用于执行和执行的任何类型的Assert合同。Equal<L>L'staticDebug

    fn compare<R: PartialEq<L> + fmt::Debug>(self, target: R) -> AssertResult {
Run Code Online (Sandbox Code Playgroud)

这违反了合同Assert,其中规定:“应提供一种可以使用实现和compare的任何类型的参数来调用的方法。” 您提供的方法不满足这些条件,但只能使用实现and的类型的参数来调用。AnyDebugcomparePartialEq<L>Debug

或者,更简洁地说:您签署了一份合同,其中规定compare<R: Any + Debug>并试图交付实际上的产品compare<R: PartialEq<L> + fmt::Debug>,而编译器很生气,因为您没有遵守合同的规定。


如何修复它?

一种可能的更正(您已经知道)如下所示:

pub trait Assert<R> {
    fn compare(self, target: R) -> AssertResult;
}
Run Code Online (Sandbox Code Playgroud)

合同规定:“实现的类型Assert<R>(其中是任何类型)应提供可以使用类型参数调用的R方法。”compareR

impl<L: fmt::Debug, R: PartialEq<L> + fmt::Debug> Assert<R> for Equal<L> {
Run Code Online (Sandbox Code Playgroud)

Assert<R>只要执行并执行和 ,Equal<L>就执行协议。LDebugRPartialEq<L>Debug

    fn compare(self, target: R) -> AssertResult {
Run Code Online (Sandbox Code Playgroud)

契约的履行:可以对 类型的参数调用的Assert方法。该方法的主体可能取决于 的知识,因为这是其“合同”条款中的。compareRR: PartialEq<L>

trait和的组合impl确定了必须履行的合同条款impl。您编写的第一件事建立了一组特定的术语,然后尝试交付compare不满足这些术语的产品(方法)。上述修复修改了条款以包括编写该compare方法所需的所有条件。