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

时间:2016-06-05 22:04:57

标签: rust

我正在学习Rust,已阅读Rust主页,并正在尝试小型示例程序。这是失败的代码:

foreach(const QString &str, patternSlices) {
   i++;       
   // suppose that your label has name label1...labelN
   QString labelName = QString("label%1").arg(i);
   QLabel* label = findChild<QLabel*>(labelName);
   if( label )
      label->setPixmap(activeStep.scaled(100,100, Qt::KeepAspectRatio));           
}

以下是错误消息:

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}
    }
}

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

3 个答案:

答案 0 :(得分:5)

Add trait定义为

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. 假设您将返回已添加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}
        }
    }
    
  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}
        }
    }
    

答案 1 :(得分:4)

add的实施会产生Complex<<T as core::ops::Add>::Output><T as core::ops::Add>::Output(即Output的{​​{1}}实施的Add<T>不保证与T相同。您可以在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>

答案 2 :(得分:0)

您需要为Add指定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}
    }
}