rust - 接收错误[E0276] : impl has stricter requirements than trait with generics

标签 rust

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

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

现在,当我想实现 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
            ))
        }
    }
}

链接到 playground .

我希望能够接受任何东西作为 LR 但在实现中限制它们。不过,我不确定这是否是正确的方法。

最佳答案

LAssert<L>没有被特性使用,所以它没有用处;我要忽略它。没有那么复杂,这是你写的:

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

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

impl<L: 'static + fmt::Debug> Assert for Equal<L> {

这是实现 Assert 的协议(protocol)契约(Contract)Equal<L>其中 L'static 的任何类型并实现 Debug .

    fn compare<R: PartialEq<L> + fmt::Debug>(self, target: R) -> AssertResult {

这违反了 Assert契约(Contract),它说:“应提供一个方法 compare 可以用实现 AnyDebug 的任何类型的参数调用。” compare您提供的方法不满足这些条件,但只能使用实现 PartialEq<L> 的类型的参数调用和 Debug .

或者,更简洁地说:你签了一份契约(Contract),上面写着 compare<R: Any + Debug>并试图交付实际上是 compare<R: PartialEq<L> + fmt::Debug> 的产品,编译器生气了,因为你没有坚持你的契约(Contract)。


如何解决?

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

pub trait Assert<R> {
    fn compare(self, target: R) -> AssertResult;
}

契约(Contract)规定,“实现 Assert<R> 的类型(其中 R 是任何类型)应提供一个方法 compare,可以使用 R 类型的参数调用。”

impl<L: fmt::Debug, R: PartialEq<L> + fmt::Debug> Assert<R> for Equal<L> {

执行协议(protocol)Assert<R>对于 Equal<L>只要L工具 DebugR工具 PartialEq<L>Debug .

    fn compare(self, target: R) -> AssertResult {

Assert 的实现契约(Contract):一种方法compare可以在 R 类型的参数上调用.此方法的主体可能取决于 R: PartialEq<L> 的知识,因为这是其“契约(Contract)”的条款。

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

关于rust - 接收错误[E0276] : impl has stricter requirements than trait with generics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46929493/

相关文章:

rust - 为什么使用 Into::into 解析字符串映射结果无法推断类型?

rust - 如何在 Rust 中将两个 i16 相加或相乘形成一个 i32 而不会溢出?

rust - 我的 Rust 代码比等效的 Python 代码长得多,结果错误

rust - 如何检查远程 UDP 端口是否打开?

generics - rust:预期的类型参数,找到的结构

oop - 为什么 Rust 不支持 trait 对象向上转换?

rust - 借用 HashMap 而不借用他的内容

struct - 我是否需要始终将基本结构放在 main() 之外以便它们是全局的?

rust - 如何在 .cargo/config 文件中使用环境变量?

rust - 收集到 HashMap 时是否可以检测冲突?