مطابقة حالات البيانات
جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 16 من 61.
في الدرس السابق، استخدمتَ match داخل أساليب التعداد للتعامل مع المتغيرات المختلفة. الآن لنركّز على كيفية قيام match فعليًا باستخراج البيانات المخزّنة داخل تلك المتغيرات: وهي تقنية تُسمّى التفكيك.
عندما تستخدم match لمطابقة متغير من enum يحمل بيانات، يمكنك ربط تلك البيانات بمتغيرات مباشرةً في النمط:
enum Event {
Click { x: i32, y: i32 },
KeyPress(char),
Resize(u32, u32),
}
fn handle_event(event: Event) {
match event {
Event::Click { x, y } => {
println!("Clicked at ({}, {})", x, y);
}
Event::KeyPress(key) => {
println!("Key pressed: {}", key);
}
Event::Resize(width, height) => {
println!("Resized to {}x{}", width, height);
}
}
}
يستخرج كل ذراع البيانات بطريقة مختلفة استنادًا إلى بنية المتغير. بالنسبة إلى المتغيرات الشبيهة بالهياكل، تستخدم { field_name } لاستخراج الحقول named. أما بالنسبة إلى متغيرات الصفوف، فتستخدم متغيرات موضعية مثل (width, height).
تصبح أسماء المتغيرات التي تختارها متاحة داخل ذراع match هذا. وهذا أمر قوي، لأنك تتحقق في الوقت نفسه من المتغيّر الذي لديك وتحصل على إمكانية الوصول إلى حمولته.
يضمن المصرّف أن تتعامل مع كل تنويعة، وتكون القيم المستخرجة جاهزة للاستخدام فورًا: لا حاجة إلى خطوات إضافية.
التحدي
سهللنبنِ معالج أوامر يتعامل مع أنواع مختلفة من أوامر المستخدم. يحمل كل أمر بيانات مختلفة، وسيستخدم المعالج مطابقة الأنماط لاستخراج تلك البيانات وإنتاج استجابات مناسبة.
ستنشئ ملفين لتنظيم التعليمات البرمجية:
command.rs: عرّف تعدادCommandعامًا مع ثلاثة تنويعات:Say: يحمل رسالةStringsingle (بصيغة tuple)Move: يحمل حقولًا named:direction(String) وsteps(u32)Calculate: يحمل قيمتين من نوعi32تمثلان عددين ستتم إضافتهما (بصيغة tuple)
executeتستخدمmatchلتفكيك كل تنويع وإرجاعStringيصف الإجراء المنفذ.main.rs: أضف وحدة الأوامر، وأنشئ مثيلًا واحدًا من كل تنويع من تنويعات الأوامر باستخدام inputs المقدمة، واستدعِ method executeعلى كل منها لطباعة results.
يجب أن تفكك method execute كل تنويع للوصول إلى بياناته وأن تعيد رسائل بهذه الصيغ exact:
- بالنسبة إلى
Say:Saying: {message} - بالنسبة إلى
Move:Moving {steps} steps {direction} - بالنسبة إلى
Calculate:{a} + {b} = {sum}
يجب أن يعرض ناتجك نتيجة كل أمر في سطر مستقل:
Saying: {message}
Moving {steps} steps {direction}
{a} + {b} = {sum}على سبيل المثال، مع رسالة Say هي "Hello world"، وأمر Move بمقدار 5 من الخطوات في الاتجاه "north"، وحساب العددين 10 و25، سيكون الناتج:
Saying: Hello world
Moving 5 steps north
10 + 25 = 35ستتلقى خمسة inputs: رسالة Say، والاتجاه، وعدد الخطوات، والعددان المطلوب حسابهما.
جرّب بنفسك
mod command;
use command::Command;
fn main() {
// اقرأ المدخلات
let mut say_message = String::new();
std::io::stdin().read_line(&mut say_message).expect("Failed to read line");
let say_message = say_message.trim().to_string();
let mut direction = String::new();
std::io::stdin().read_line(&mut direction).expect("Failed to read line");
let direction = direction.trim().to_string();
let mut steps_input = String::new();
std::io::stdin().read_line(&mut steps_input).expect("Failed to read line");
let steps: u32 = steps_input.trim().parse().expect("Failed to parse steps");
let mut num1_input = String::new();
std::io::stdin().read_line(&mut num1_input).expect("Failed to read line");
let num1: i32 = num1_input.trim().parse().expect("Failed to parse num1");
let mut num2_input = String::new();
std::io::stdin().read_line(&mut num2_input).expect("Failed to read line");
let num2: i32 = num2_input.trim().parse().expect("Failed to parse num2");
// TODO: أنشئ أمر Say باستخدام say_message ونفّذه
// TODO: أنشئ أمر Move باستخدام direction و steps، ونفّذه
// TODO: أنشئ أمر Calculate باستخدام num1 و num2، ونفّذه
// TODO: اطبع نتائج تنفيذ كل أمر
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائطتدرّب بنفسك: مترجم Rust عبر الإنترنت