递归地实现特征“Not”

ram*_*mbi 2 types operator-overloading traits rust

我有一个Couple带有类型参数的 rust结构

我想对此实施一个操作(Not在这种情况下)Couple<T>:如果T实施Not,这对夫妇的否定就是否定的夫妇。

use std::ops::Not;

struct Couple<T>(T, T);

impl<T> Not for Couple<T>
where
    T: Not,
{
    type Output = Self;

    fn not(self) -> Self {
        Couple(T::not(self.0), T::not(self.1))
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码与其他特征(例如 Default::default)一起编译,但不与 trait Not

我收到错误

error[E0308]: mismatched types
  --> src/lib.rs:12:16
   |
5  | impl<T> Not for Couple<T>
   |      - this type parameter
...
12 |         Couple(T::not(self.0), T::not(self.1))
   |                ^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
   |
   = note: expected type parameter `T`
             found associated type `<T as Not>::Output`
help: consider further restricting this bound
   |
7  |     T: Not + Not<Output = T>,
   |            ^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

为什么会这样?我如何为 实现Not和其他操作特性Couple

Val*_*tin 8

实施Not for T并不意味着它一定会返回T。因此,您必须Output通过执行 eg来指定类型Not<Output = T>

use std::ops::Not;

struct Couple<T>(T, T);

impl<T> Not for Couple<T>
where
    T: Not<Output = T>,
{
    type Output = Self;

    fn not(self) -> Self {
        Couple(T::not(self.0), T::not(self.1))
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您想允许基于 的不同Output类型<T as Not>::Output,则可以改为执行以下操作:

impl<T> Not for Couple<T>
where
    T: Not,
{
    type Output = Couple<T::Output>;

    fn not(self) -> Self::Output {
        Couple(T::not(self.0), T::not(self.1))
    }
}
Run Code Online (Sandbox Code Playgroud)

您当然也可以简化Couple(T::not(self.0), T::not(self.1))Couple(!self.0, !self.1).