Menu
Coddy logo textTech

Трейты равенства

Часть раздела Объектно-ориентированное программирование путешествия по Rust на Coddy. Урок 38 из 61.

Сравнение двух instances пользовательского struct с помощью == по умолчанию не работает в Rust. Компилятор не знает, как определить, равны ли два struct. Нужно сообщить ему это, реализовав трейт PartialEq.

Как и Debug и Copy, можно автоматически derive 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

При использовании derive PartialEq сравнивает каждое поле структуры. Два экземпляра равны только в том случае, если все их соответствующие поля совпадают.

Вы также встретите Eq — это маркерный трейт, который обозначает полное равенство, то есть каждое значение равно самому себе. Большинство типов удовлетворяют этому условию, но числа с плавающей точкой — нет (потому что NaN != NaN). Для структур с целочисленными полями можно безопасно выполнить derive обоих трейтов:

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

У Eq нет собственных методов. Он просто указывает, что тип обладает рефлексивным равенством. Некоторые возможности стандартной библиотеки требуют Eq в дополнение к PartialEq, поэтому для подходящих типов обычно выводят оба трейта вместе.

challenge icon

Задание

Легко

Давайте создадим систему сопоставления цветов, которая демонстрирует, как traits PartialEq и Eq позволяют сравнивать экземпляры struct!

Вы создадите два файла, чтобы организовать логику сравнения цветов:

  • color.rs: Определите public struct Color с тремя public полями: red, green и blue (все типа u8). Выведите traits PartialEq и Eq, чтобы два цвета можно было сравнивать с помощью ==. При использовании derive 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

Вы получите шесть входных значений: RGB-значения для первого цвета (три значения), за которыми следуют RGB-значения для второго цвета (три значения). Выполните parse каждого значения как u8.

Попробуйте сами

mod color;

use color::Color;

fn main() {
    // Прочитать шесть значений 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: Compare the two colors using == and print: Colors match: {true/false}
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Rust