我正在尝试定义一个特征来比较两个给定的参数并根据实现返回一个 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 .
我希望能够接受任何东西作为 L
和 R
但在实现中限制它们。不过,我不确定这是否是正确的方法。
最佳答案
L
在Assert<L>
没有被特性使用,所以它没有用处;我要忽略它。没有那么复杂,这是你写的:
pub trait Assert {
fn compare<R: Any + Debug>(self, target: R) -> AssertResult;
}
这是一个约定,“当一个类型实现了 Assert
时,它应该提供一个方法 compare
可以用实现 Any
和 Debug
的任何类型的参数调用。”
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
可以用实现 Any
和 Debug
的任何类型的参数调用。” 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
工具 Debug
和 R
工具 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/