返回添加两个泛型的结果时的类型不匹配



我正在学习 Rust,已经阅读了 Rust 主页,并且正在尝试一些小的示例程序。下面是失败的代码:

use std::ops::Add;
pub struct Complex<T> {
pub re: T,
pub im: T,
}
impl <T: Add> Add<Complex<T>> for Complex<T> {
type Output = Complex<T>;
fn add(self, other: Complex<T>) -> Complex<T> {
Complex {re: self.re + other.re, im: self.im + other.im}
}
}

以下是错误消息:

src/lib.rs:11:3: 11:59 error: mismatched types:
expected `Complex<T>`,
found `Complex<<T as core::ops::Add>::Output>`
(expected type parameter,
found associated type) [E0308]
src/lib.rs:11       Complex {re: self.re + other.re, im: self.im + other.im}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我不明白为什么它无法编译。

Add特征定义为

pub trait Add<RHS = Self> {
type Output;
fn add(self, rhs: RHS) -> Self::Output;
}

也就是说,给定一个用于Self的类型(实现特征的类型)和一个用于右侧的类型(RHS,要添加的东西),将产生一个唯一的类型:Output

从概念上讲,这允许您创建一个类型A,该类型可以向其添加B类型,这将始终生成第三个类型C

在您的示例中,您限制了T实现Add。默认情况下,假定RHS类型与为其实现特征的类型相同 (RHS = Self)。但是,对输出类型必须是什么没有任何限制。

有两种可能的解决方案:

  1. 假设您将返回一个已由添加T的结果类型参数化的Complex

    impl<T> Add<Complex<T>> for Complex<T>
    where
    T: Add,
    {
    type Output = Complex<T::Output>;
    fn add(self, other: Complex<T>) -> Complex<T::Output> {
    Complex {
    re: self.re + other.re,
    im: self.im + other.im,
    }
    }
    }
    
  2. T限制为那些在添加到自身时返回相同类型的类型:

    impl<T> Add<Complex<T>> for Complex<T>
    where
    T: Add<Output = T>,
    {
    type Output = Complex<T>;
    fn add(self, other: Complex<T>) -> Complex<T> {
    Complex {
    re: self.re + other.re,
    im: self.im + other.im,
    }
    }
    }
    

另请参阅:

  • 如何要求泛型类型在泛型函数中实现 Add、Sub、Mul 或 Div 等操作?
  • 如何编写用于添加两个泛型类型的引用的 Trait 绑定?

您对add的实现会产生一个Complex<<T as core::ops::Add>::Output><T as core::ops::Add>::Output(即T实施Add<T>Output)不保证与T相同。可以在Output关联类型上添加约束,以将实现限制为仅在它们实际上相同时才可用:

impl<T: Add<Output = T>> Add for Complex<T> {
type Output = Complex<T>;
fn add(self, other: Complex<T>) -> Complex<T> {
Complex { re: self.re + other.re, im: self.im + other.im }
}
}

或者,你可以通过添加Complex<T>Complex<U>来更改你的实现,尽可能通用,前提是可以添加一个T和一个U,并返回一个Complex<<T as Add<U>>::Output>

impl<T: Add<U>, U> Add<Complex<U>> for Complex<T> {
type Output = Complex<<T as Add<U>>::Output>;
fn add(self, other: Complex<U>) -> Self::Output {
Complex { re: self.re + other.re, im: self.im + other.im }
}
}

您需要为T指定Add的输出类型:

impl <T: Add<Output = T>> Add for Complex<T> {
type Output = Complex<T>;
fn add(self, other: Complex<T>) -> Complex<T> {
Complex {re: self.re + other.re, im: self.im + other.im}
}
}

相关内容

最新更新