سمات المساواة
جزء من قسم 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، لذا فمن الشائع اشتقاق كليهما معاً للأنواع التي تستوفي الشروط.
التحدي
سهللنقم ببناء نظام مطابقة ألوان يوضح كيف تمكن سمات (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}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس Object Oriented Programming
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائط