2016-08-26 4 views
3

Я изучаю ржавчину, и я не понимаю, почему следующий код дает ошибку.Ошибка при использовании операторов с общим типом

use std::ops::Mul; 
use std::ops::Add; 

struct Vec2<T> 
{ 
    x: T, 
    y: T, 
} 

impl<T: Mul + Add> Vec2<T> { 
    fn magnitude_squared(&self) -> T { 
     self.x * self.x + self.y * self.y // error here 
    } 
} 

fn main() { 
    let x = Vec2 { x: 1f32, y: 1f32 }; 
    println!("{}", x.magnitude_squared()); 
} 

Сообщение об ошибке (не имеет большого смысла для меня, если умножение двух поплавков производит некоторый тип 'не-addable'):

ЦСИ \ main.rs (14,9): ошибка E0369: бинарная операция + не может быть применена к типу <T as std::ops::Mul>::Output
помощи: запустить rustc --explain E0369, чтобы увидеть подробное объяснение
примечания: реализация std::ops::Add может отсутствовать для <T as std::ops::Mul>::Output

rustc 1.11.0 (9b21dcd6a 2016-08-15) Ржавчина Компилятор
код аналогичен примеру this. Какая разница, что делает мой код неправильным?

ответ

3

Сообщение об ошибке сообщает вам, что делать: вам нужно добавить реализацию Add для <T as Mul>::Output.

Вы можете сделать это, добавив признак, связанный с вашей impl как таковой:

use std::ops::Mul; 
use std::ops::Add; 

struct Vec2<T: Copy> 
{ 
    x: T, 
    y: T, 
} 

impl<T> Vec2<T> 
    where T: Copy + Mul, 
      <T as Mul>::Output: Add<Output=T> 
{ 
    fn magnitude_squared(&self) -> T { 
     self.x * self.x + self.y * self.y 
    } 
} 

fn main() { 
    let x = Vec2 { x: 1f32, y: 1f32 }; 
    println!("{}", x.magnitude_squared()); 
} 

Copy был добавлен, чтобы упростить этот ответ.

+0

Я правильно понимаю, что в вашем решении 'T * T' может быть совершенно другим типом' M', если добавление двух 'M' вместе снова дает' T'? –

+0

@ChrisEmerson: Да, вы правы. – antoyo

+0

Правильно ли сказать, что компилятор ржавчины проверяет тип перед заменой, поэтому необходимо явно указать черты для типов признаков? (Надеюсь, моя формулировка имеет смысл). –

Смежные вопросы