Rust 中的运算符重载

Beginner

This tutorial is from open-source community. Access the source code

简介

在本实验中,我们将探索 Rust 中的运算符重载,以及如何通过 trait 来实现它。Rust 中的运算符可以使用 trait 进行重载,这使得它们能够根据输入参数执行不同的任务。例如,+ 运算符是 add 方法的语法糖,任何实现了 Add trait 的类型都可以使用它。包括 Add 在内的用于重载运算符的 trait 可以在 core::ops 中找到。提供的 Rust 代码展示了如何为自定义类型 FooBar 重载 + 运算符,分别得到不同的输出类型 FooBarBarFoo

注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用 main.rs,并通过 rustc main.rs &&./main 进行编译和运行。

运算符重载

在 Rust 中,许多运算符都可以通过 trait 进行重载。也就是说,某些运算符可以根据其输入参数来完成不同的任务。这是可行的,因为运算符是方法调用的语法糖。例如,a + b 中的 + 运算符会调用 add 方法(就像 a.add(b) 一样)。这个 add 方法是 Add trait 的一部分。因此,任何实现了 Add trait 的类型都可以使用 + 运算符。

core::ops 中可以找到一系列用于重载运算符的 trait,比如 Add

use std::ops;

struct Foo;
struct Bar;

#[derive(Debug)]
struct FooBar;

#[derive(Debug)]
struct BarFoo;

// `std::ops::Add` trait 用于指定 `+` 的功能。
// 这里,我们定义 `Add<Bar>` - 表示与右侧类型为 `Bar` 的加法操作的 trait。
// 以下代码块实现了该操作: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` 的加法操作的 trait。
// 此代码块实现了该操作: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 中练习更多实验来提升你的技能。