Menu
CoddyTech

Các trait so sánh bằng

Thuộc phần Lập trình hướng đối tượng trong hành trình Rust của Coddy. Bài học 38 trên 61.

Trong Rust, theo mặc định, bạn không thể so sánh hai đối tượng của một struct tùy chỉnh bằng ==. Trình biên dịch không biết cách xác định hai struct có bằng nhau hay không. Bạn cần cho trình biên dịch biết bằng cách triển khai trait PartialEq.

Giống như Debug và Copy, bạn có thể tự động suy ra 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

Khi được tự động tạo, PartialEq sẽ so sánh từng trường của struct. Hai instance chỉ bằng nhau khi tất cả các trường tương ứng đều trùng khớp.

Bạn cũng sẽ gặp Eq, đây là một trait đánh dấu, cho biết tính bằng nhau toàn phần, nghĩa là mọi giá trị đều bằng chính nó. Hầu hết các kiểu đều thỏa mãn điều này, nhưng số dấu phẩy động thì không (vì NaN != NaN). Với các struct có trường kiểu số nguyên, bạn có thể dẫn xuất an toàn cả hai trait:

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

Eq không có phương thức riêng. Nó chỉ báo hiệu rằng kiểu dữ liệu có tính đẳng thức phản xạ. Một số tính năng trong thư viện chuẩn yêu cầu Eq bên cạnh PartialEq, vì vậy các kiểu dữ liệu đáp ứng điều kiện thường được suy diễn cả hai trait cùng lúc.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống so khớp màu để minh họa cách các trait PartialEq và Eq cho phép so sánh các instance của struct!

Bạn sẽ tạo hai tệp để sắp xếp logic so sánh màu:

  • color.rs: Định nghĩa một struct Color công khai với ba trường công khai: red, green và blue (đều có kiểu u8). Dẫn xuất cả PartialEq và Eq để có thể so sánh hai màu bằng ==. Khi được dẫn xuất, Rust chỉ xem hai màu là bằng nhau nếu cả ba thành phần RGB khớp chính xác.
  • main.rs: Đưa module màu vào và tạo hai instance Color bằng các đầu vào đã cho. So sánh chúng bằng == rồi in ra liệu chúng có khớp hay không.

Đầu ra của bạn cần cho biết hai màu có giống nhau hay không:

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

Ví dụ, với các đầu vào 255, 128, 0, 255, 128, 0:

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

Và với các đầu vào 100, 100, 100, 200, 200, 200:

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

Bạn sẽ nhận sáu đầu vào: các giá trị RGB của màu thứ nhất (ba giá trị), tiếp theo là các giá trị RGB của màu thứ hai (ba giá trị). Phân tích mỗi giá trị thành u8.

Tự làm thử

mod color;

use color::Color;

fn main() {
    // Đọc sáu giá trị 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: Tạo hai instance Color bằng các giá trị đã phân tích

    // TODO: In Color 1 theo định dạng: Color 1: rgb(r, g, b)

    // TODO: In Color 2 theo định dạng: Color 2: rgb(r, g, b)

    // TODO: So sánh hai màu bằng == rồi in ra: Colors match: {true/false}
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Rust online