Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

سمات المساواة

جزء من قسم Object Oriented Programming في رحلة Rust على Coddy — الدرس 38 من 61.

مقارنة مثيلين من هيكل (struct) مخصص باستخدام == لا تعمل بشكل افتراضي في لغة 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 كل حقل من حقول الـ struct. ويكون المثيلان متساويين فقط إذا تطابقت جميع الحقول المقابلة لهما.

ستصادف أيضًا Eq، وهي سمة علامة (marker trait) تشير إلى المساواة التامة—مما يعني أن كل قيمة تساوي نفسها. معظم الأنواع تستوفي هذا الشرط، لكن أرقام الفاصلة العائمة لا تفعل ذلك (لأن NaN != NaN). بالنسبة للهياكل (structs) التي تحتوي على حقول أعداد صحيحة، يمكنك اشتقاق كليهما بأمان:

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

ليس لدى Eq أي دوال خاصة به—فهو ببساطة يشير إلى أن النوع يمتلك مساواة انعكاسية. تتطلب بعض ميزات المكتبة القياسية Eq بالإضافة إلى PartialEq، لذا فمن الشائع اشتقاق كليهما معاً للأنواع التي تستوفي الشروط.

challenge icon

التحدي

سهل

لنقم ببناء نظام مطابقة ألوان يوضح كيف تمكن سمات (traits) PartialEq و Eq من المقارنة بين مثيلات الهياكل (struct instances)!

ستقوم بإنشاء ملفين لتنظيم منطق مقارنة الألوان الخاص بك:

  • color.rs: قم بتعريف هيكل Color عام (public) مع ثلاثة حقول عامة: red، و green، و blue (جميعها من نوع u8). قم باشتقاق (Derive) كل من PartialEq و Eq بحيث يمكن مقارنة لونين باستخدام ==. عند الاشتقاق، سيعتبر 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 للون الثاني (ثلاث قيم). قم بتحليل كل منها كـ u8.

ورقة مرجعية

لمقارنة الهياكل (structs) المخصصة باستخدام ==، قم بتنفيذ سمة (trait) الـ PartialEq عن طريق اشتقاقها:

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

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

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

عند الاشتقاق، تقوم PartialEq بمقارنة جميع الحقول — يكون المثيلان متساويين فقط إذا تطابقت جميع الحقول المتقابلة.

سمة Eq هي سمة علامة (marker trait) تشير إلى المساواة الكاملة (كل قيمة تساوي نفسها). معظم الأنواع تحقق ذلك، باستثناء أرقام الفاصلة العائمة (لأن NaN != NaN). بالنسبة للهياكل التي تحتوي على حقول أعداد صحيحة، قم باشتقاق كلتا السمتين معاً:

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

لا تحتوي Eq على دوال — فهي تشير إلى المساواة الانعكاسية. تتطلب بعض ميزات المكتبة القياسية وجود Eq بالإضافة إلى PartialEq.

جرّب بنفسك

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: مقارنة اللونين باستخدام == وطباعة: Colors match: {true/false}
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming