Menu
CoddyTech

相等性 Trait

本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 38 课,共 61 课。

在 Rust 中,默认情况下,无法使用 == 比较两个自定义结构体实例。编译器不知道如何判断两个结构体是否相等。你需要实现 PartialEq 特征来告诉编译器。

和 Debug、Copy 一样,你可以自动派生 PartialEq:

#[derive(PartialEq)]
struct Coordinate {
    x: i32,
    y: i32,
}

let a = Coordinate { x: 5, y: 10 };
let b = Coordinate { x: 5, y: 10 };
let c = Coordinate { x: 3, y: 7 };

println!("{}", a == b);  // true
println!("{}", a == c);  // false

派生 PartialEq 时,会比较结构体的每个字段。只有所有对应字段都匹配时,两个实例才相等。

你还会遇到 Eq,它是一种标记特征,表示完全相等,也就是说,每个值都等于自身。大多数类型都满足这一点,但浮点数不满足(因为 NaN != NaN)。对于包含整数属性的结构体,你可以安全地派生这两种特征:

#[derive(PartialEq, Eq)]
struct Coordinate {
    x: i32,
    y: i32,
}

Eq 没有自己的方法。它只是表示该类型具有自反相等性。一些标准库功能除了要求 PartialEq,还要求 Eq,因此对于符合条件的类型,通常会同时派生这两个特征。

challenge icon

挑战

简单

让我们构建一个颜色匹配系统,演示 PartialEq 和 Eq trait 如何支持比较结构体实例!

你将创建两个文件来整理颜色比较逻辑:

  • color.rs:定义一个公共的 Color 结构体,其中包含三个公共字段:red、green 和 blue(类型均为 u8)。派生 PartialEq 和 Eq,这样就可以使用 == 比较两个颜色。派生这两个 trait 后,Rust 只有在三个 RGB 分量完全匹配时,才会认为两个颜色相等。
  • main.rs:引入颜色模块,并使用提供的输入创建两个 Color 实例。使用 == 比较它们,并输出它们是否匹配。

输出应说明这两个颜色是否相同:

Color 1: rgb({r1}, {g1}, {b1})
Color 2: rgb({r2}, {g2}, {b2})
Colors match: {true/false}

例如,输入 255、128、0、255、128、0 时:

Color 1: rgb(255, 128, 0)
Color 2: rgb(255, 128, 0)
Colors match: true

输入 100、100、100、200、200、200 时:

Color 1: rgb(100, 100, 100)
Color 2: rgb(200, 200, 200)
Colors match: false

你将收到 6 个输入:第一个颜色的 RGB 值(3 个值),接着是第二个颜色的 RGB 值(3 个值)。将每个值解析为 u8。

亲手试试

mod color;

use color::Color;

fn main() {
    // 读取 6 个 RGB 值
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let r1: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let g1: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let b1: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let r2: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let g2: u8 = input.trim().parse().expect("Invalid input");

    input.clear();
    std::io::stdin().read_line(&mut input).expect("Failed to read line");
    let b2: u8 = input.trim().parse().expect("Invalid input");

    // TODO: 用解析出的值创建两个 Color 实例

    // TODO: 按以下格式打印 Color 1:Color 1: rgb(r, g, b)

    // TODO: 按以下格式打印 Color 2:Color 2: rgb(r, g, b)

    // TODO: 用 == 比较这两种颜色,并打印:Colors match: {true/false}
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Rust 在线编译器