简体   繁体   English

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

[英]Mismatched types when returning the result of adding two generics

I am learning Rust, have read the Rust homepage, and am trying out small example programs.我正在学习 Rust,已阅读 Rust 主页,并正在尝试小示例程序。 Here is code that fails:这是失败的代码:

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

Here is the error message:这是错误消息:

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

I don't understand why it fails to compile.我不明白为什么它无法编译。

The Add trait is defined as Add特征定义为

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

That is, given a type for Self (the type the trait is implemented for), and a type for the right-hand-side ( RHS , the thing being added), there will be a unique type that is produced: Output .也就是说,给定一个Self类型(实现 trait 的类型)和一个右手边的类型( RHS ,被添加的东西),将产生一个唯一的类型: Output

Conceptually, this allows you to create a type A that can have a type B added to it, which will always produce a third type C .从概念上讲,这允许您创建一个类型A ,该类型可以添加一个类型B ,这将始终生成第三个类型C

In your example, you have constrained T to implement Add .在您的示例中,您已约束T来实现Add By default, the RHS type is assumed to be the same as the type the trait is implemented for ( RHS = Self ).默认情况下,假定RHS类型与实现 trait 的类型相同( RHS = Self )。 However, there are no restrictions placed on what the output type must be.但是,对于输出类型必须是什么没有限制。

There are two potential solutions:有两种可能的解决方案:

  1. Say that you will return a Complex that has been parameterized by whatever the result type of adding T is:假设您将返回一个Complex ,该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. Restrict T to those types that when added to themselves return the same type: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, } } }

See also:另见:

Your implementation of add produces a Complex<<T as core::ops::Add>::Output> .您的add实现会产生一个Complex<<T as core::ops::Add>::Output> <T as core::ops::Add>::Output (ie the Output of the implementation of Add<T> for T ) is not guaranteed to be the same as T . <T as core::ops::Add>::Output (即, Output的执行的Add<T>T )不能保证是相同的T You can add a constraint on the Output associated type to restrict your implementation to be only available when they are in fact the same:您可以在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 }
    }
}

Or, you could change your implementation to be as generic as possible by making it possible to add a Complex<T> and a Complex<U> , provided that it is possible to add a T and a U , and by returning a Complex<<T as Add<U>>::Output> .或者,您可以通过添加一个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 }
    }
}

You need to specify the output type of Add for T :您需要为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}
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM