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

Tho*_*357 4 rust

我正在学习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}
    }
}
Run Code Online (Sandbox Code Playgroud)

这是错误消息:

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}
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

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

She*_*ter 5

所述Add性状被定义为

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

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

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

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

有两种可能的解决方案:

  1. 假设您将返回Complex已通过添加的结果类型参数化的参数T:

    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}
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  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}
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)


Lee*_*Lee 0

您需要指定Addfor的输出类型T

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}
    }
}
Run Code Online (Sandbox Code Playgroud)