Rust. Перегрузка операторов для пользовательского типа данных
Я хотел написать небольшой код на rust`e но столкнулся с некоторыми трудностями. Я сделал struct Vector с тремя полями одного типа и для него мне нужно перегрузить операторы сложения, вычитания и умножения. Попытка перегрузить оператор сложения не удалась, хотя я все делал по примерам из книг и интернета. Вот сам код:
use std::ops::Add;
struct Vector<T> {
x1: T,
x2: T,
x3: T,
}
impl<T> Add<T> for Vector<T>
{
type Output = Vector<T>;
fn add(self, rhs: Vector<T>) -> Vector<T> {
Vector {x1: self.x1 + rhs.x1, x2: self.x2 + rhs.x2, x3: self.x3 + rhs.x3};
}
}
fn main() {
let vector1 = Vector { x1: 5.6, x2: 7.2, x3: 2.5 };
let vector2 = Vector { x1: -0.1, x2: 10.9, x3: 3.3 };
println!("Вектор 1: ({}, {}, {})", vector1.x1, vector1.x2, vector1.x3);
println!("Вектор 2: ({}, {}, {})", vector2.x1, vector2.x2, vector2.x3);
let vector3 = vector1 + vector2;
println!("Сумма векторов: ({}, {}, {})", vector3.x1, vector3.x2, vector3.x3);
}
Ошибка:
error[E0053]: method `add` has an incompatible type for trait
--> main.rs:13:5
|
13 | / fn add(self, rhs: Vector<T>) -> Vector<T> {
14 | | Vector {x1: self.x1 + rhs.x1, x2: self.x2 + rhs.x2, x3: self.x3 + rhs.x3};
15 | | }
| |_____^ expected type parameter, found struct `Vector`
|
= note: expected type `fn(Vector<T>, T) -> Vector<T>`
found type `fn(Vector<T>, Vector<T>) -> Vector<T>`
error: aborting due to previous error(s)
Писал и компилировал в онлайн компиляторе. Заранее спасибо.
Ответы (2 шт):
Автор решения: Ainar-G
→ Ссылка
Как-то так:
impl<T: Add<Output = T>> Add<Vector<T>> for Vector<T> {
type Output = Vector<T>;
fn add(self, rhs: Vector<T>) -> Vector<T> {
Vector {
x1: self.x1 + rhs.x1,
x2: self.x2 + rhs.x2,
x3: self.x3 + rhs.x3,
}
}
}
Автор решения: Denis Kotlyarov
→ Ссылка
Набросал вам полный пример с исправлением ваших ошибок.
Код:
use core::ops::Mul;
use core::ops::Sub;
use std::ops::Add;
struct Vector<T> {
x1: T,
x2: T,
x3: T,
}
/* сложение */
/* ошибка в Add<T> */
/* вы указали добавить тип T, хотя явно желали Vector<T> */
/* поэтому Add<T> -> Add<Vector<T>>*/
/* советую читать онлайн документацию */
// https://doc.rust-lang.org/std/ops/trait.Add.html
impl<T> Add</*T*/ Vector<T>> for Vector<T> where T: Add<Output = T> /* мы описали where для того чтобы любой T внутри функции можно было сложить с T*/ {
type Output = Vector<T>;
fn add(self, rhs: Vector<T>) -> Vector<T> {
Vector {
x1: self.x1 + rhs.x1, /* у вас любой тип T, не обязательно у типа данных */
x2: self.x2 + rhs.x2, /* T есть сложение, опишите это в where !! */
x3: self.x3 + rhs.x3
} //; ошибка, вы хотите вернуть значение (используйте return или опустите знак ;)
}
}
// вычитание
// https://doc.rust-lang.org/std/ops/trait.Sub.html
impl<T> Sub<Vector<T>> for Vector<T> where T: Sub<Output = T> /* мы описали where для того чтобы любой T внутри функции можно было вычесть с T*/ {
type Output = Vector<T>;
fn sub(self, rhs: Vector<T>) -> Vector<T> {
Vector {
x1: self.x1 - rhs.x1,
x2: self.x2 - rhs.x2,
x3: self.x3 - rhs.x3
}
}
}
// умножение
// https://doc.rust-lang.org/std/ops/trait.Mul.html
impl<T> Mul<Vector<T>> for Vector<T> where T: Mul<Output = T> /* мы описали where для того чтобы любой T внутри функции можно было умножить с T*/ {
type Output = Vector<T>;
fn mul(self, rhs: Vector<T>) -> Vector<T> {
Vector {
x1: self.x1 * rhs.x1,
x2: self.x2 * rhs.x2,
x3: self.x3 * rhs.x3
}
}
}
/* все операторы сложения, умножения, ...*/
/* можно получить по пути */
/* https://doc.rust-lang.org/std/ops/index.html */
fn main() {
/* сумма */
let vector1 = Vector { x1: 5.6, x2: 7.2, x3: 2.5 };
let vector2 = Vector { x1: -0.1, x2: 10.9, x3: 3.3 };
let vector3 = vector1 + vector2;
println!("Сумма векторов: ({}, {}, {})", vector3.x1, vector3.x2, vector3.x3);
/* разница */
let vector1 = Vector { x1: 5.6, x2: 7.2, x3: 2.5 };
let vector2 = Vector { x1: -0.1, x2: 10.9, x3: 3.3 };
let vector4 = vector1 - vector2;
println!("Разница векторов: ({}, {}, {})", vector4.x1, vector4.x2, vector4.x3);
/* умножение */
let vector1 = Vector { x1: 5.6, x2: 7.2, x3: 2.5 };
let vector2 = Vector { x1: -0.1, x2: 10.9, x3: 3.3 };
let vector4 = vector1 * vector2;
println!("Умножение векторов: ({}, {}, {})", vector4.x1, vector4.x2, vector4.x3);
/*
Сумма векторов: (5.5, 18.1, 5.8)
Разница векторов: (5.699999999999999, -3.7, -0.7999999999999998)
Умножение векторов: (-0.5599999999999999, 78.48, 8.25)
*/
}
Советы:
- В расте придерживайтесь общего стиля введения кода (Вы начали прямо как в си раскидывать '{' на новой строке).
- Читайте дополнительно онлайн документацию https://doc.rust-lang.org/std/index.html
- По расту достаточно книг для новичков.
- Есть официальное русское сообщество для новичков по расту в телеге (https://t.me/rust_beginners_ru).
/дополнено/
- Поставьте VsCode IDE с плагином Rust, не пишите в онлайне.
Вперёд!