Введение
В этом лабораторном задании мы исследуем перегрузку операторов в Rust и то, как это можно достичь с использованием трейтов. Операторы в Rust можно перегрузить с использованием трейтов, что позволяет им выполнять разные задачи в зависимости от входных аргументов. Например, оператор + является синтаксическим сахаром для метода add и может использоваться любым реализатором трейта Add. Трейты, которые перегружают операторы, включая Add, можно найти в core::ops. Предоставленный код на Rust демонстрирует, как перегрузить оператор + для пользовательских типов Foo и Bar, в результате чего получаются разные типы вывода FooBar и BarFoo соответственно.
Примечание: Если лабораторная работа не уточняет имя файла, вы можете использовать любое имя файла, которое хотите. Например, вы можете использовать
main.rs, скомпилировать и запустить его с помощьюrustc main.rs &&./main.
Перегрузка операторов
В Rust многие операторы можно перегрузить с помощью трейтов. То есть некоторые операторы могут использоваться для выполнения различных задач в зависимости от своих входных аргументов. Это возможно, потому что операторы являются синтаксическим сахаром для вызовов методов. Например, оператор + в a + b вызывает метод add (как в a.add(b)). Этот метод add является частью трейта Add. Следовательно, оператор + может использоваться любым реализатором трейта Add.
Список трейтов, таких как Add, которые перегружают операторы, можно найти в core::ops.
use std::ops;
struct Foo;
struct Bar;
#[derive(Debug)]
struct FooBar;
#[derive(Debug)]
struct BarFoo;
// Трейт `std::ops::Add` используется для определения функциональности `+`.
// Здесь мы определяем `Add<Bar>` - трейт для сложения с правым операндом типа `Bar`.
// Следующий блок реализует операцию: Foo + Bar = FooBar
impl ops::Add<Bar> for Foo {
type Output = FooBar;
fn add(self, _rhs: Bar) -> FooBar {
println!("> Foo.add(Bar) was called");
FooBar
}
}
// Меняя местами типы, мы получаем некоммутативное сложение.
// Здесь мы определяем `Add<Foo>` - трейт для сложения с правым операндом типа `Foo`.
// Этот блок реализует операцию: Bar + Foo = BarFoo
impl ops::Add<Foo> for Bar {
type Output = BarFoo;
fn add(self, _rhs: Foo) -> BarFoo {
println!("> Bar.add(Foo) was called");
BarFoo
}
}
fn main() {
println!("Foo + Bar = {:?}", Foo + Bar);
println!("Bar + Foo = {:?}", Bar + Foo);
}
Резюме
Поздравляем! Вы завершили лабораторную работу по перегрузке операторов. Вы можете практиковаться в других лабораторных работах в LabEx, чтобы улучшить свои навыки.