مراجعة التعداد Option
جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 17 من 61.
لقد صادفتَ بالفعل Option<T> في Rust: إنه التعداد القياسي لتمثيل القيم التي قد تكون موجودة أو غير موجودة. والآن لنلقِ نظرةً عليه من منظور البرمجة كائنية التوجه: Option ليس مجرد تعداد، بل هو نوع يحتوي على أساليب مضمّنة قوية تتيح لك التعامل مع القيم القابلة لأن تكون فارغة بأمان وأناقة.
بدلًا من إجراء المطابقة في كل مرة، يمكنك استخدام أساليب مباشرةً على قيم Option. تُرجع أسلوب unwrap_or القيمة الداخلية إذا كانت موجودة، أو قيمة افتراضية تحددها:
let maybe_name: Option<String> = Some(String::from("Alice"));
let name = maybe_name.unwrap_or(String::from("Guest"));
println!("{}", name); // Alice
let empty: Option<String> = None;
let fallback = empty.unwrap_or(String::from("Guest"));
println!("{}", fallback); // Guest
تعمل الطريقة map على تحويل القيمة الداخلية إذا كانت موجودة، مع إبقاء None دون تغيير. يتيح لك ذلك تسلسل العمليات دون التحقق باستمرار من None:
let maybe_num: Option<i32> = Some(5);
let doubled = maybe_num.map(|x| x * 2);
println!("{:?}", doubled); // Some(10)
let nothing: Option<i32> = None;
let still_nothing = nothing.map(|x| x * 2);
println!("{:?}", still_nothing); // None
تجسّد هذه الأساليب مبادئ البرمجة كائنية التوجه: يغلّف النوع Option مفهوم «ربما توجد قيمة» ويوفّر واجهة واضحة للتعامل معها. تستدعي الأساليب على الكائن بدلًا من كتابة منطق خارجي لفحصه.
التحدي
سهللنبنِ نظامًا لملفات تعريف المستخدمين يتعامل بسلاسة مع البيانات الاختيارية باستخدام أساليب Option. قد يكون لدى المستخدمين لقب معيّن، وقد لا يكون لديهم لقب. سيتعامل نظامك مع كلتا الحالتين بأناقة دون إجراء مطابقة صريحة.
ستنشئ ملفين لتنظيم التعليمات البرمجية:
profile.rs: عرّف بنيةProfileعامة تحتوي على حقلين:username(String) وnickname(Option<String>). نفّذ ما يلي:- منشئ
newيأخذ اسم مستخدم ولقبًا اختياريًا - أسلوب
display_nameيعيد اللقب إذا كان موجودًا، أو اسم المستخدم كقيمةfallback: استخدمunwrap_orللتعامل مع ذلك - أسلوب
formatted_nicknameيعيدOption<String>مع إحاطة اللقب بين قوسين مربعين (مثل"[CoolNick]") إذا كان موجودًا، أوNoneإذا لم يكن هناك لقب: استخدمmapلتحويل القيمة
- منشئ
main.rs: استورد وحدة profile وأنشئ ملفي تعريف: أحدهما مع لقب والآخر بدونه. اعرض كلا الأسلوبين على كل ملف تعريف لتوضيح كيفية تعامل أساليبOptionبشكل مختلف مع القيم الموجودة وغير الموجودة.
بالنسبة إلى أسلوب formatted_nickname، استخدم تنسيق التصحيح ({:?}) عند الطباعة لأنه يعيد قيمة من النوع Option.
يجب أن يتبع الإخراج هذا التنسيق الدقيق، مع عرض ملفي التعريف:
Display name: {name}
Formatted nickname: {option}
Display name: {name}
Formatted nickname: {option}على سبيل المثال، مع ملف تعريف لاسم المستخدم "alice" ولقب "Ace"، وآخر لاسم المستخدم "bob" دون لقب، سيكون الإخراج كما يلي:
Display name: Ace
Formatted nickname: Some("[Ace]")
Display name: bob
Formatted nickname: Noneستتلقى ثلاثة مدخلات: اسم المستخدم الأول، ولقب المستخدم الأول، واسم المستخدم الثاني (الذي ليس لديه لقب).
جرّب بنفسك
mod profile;
use profile::Profile;
fn main() {
// اقرأ المدخلات
let mut input1 = String::new();
std::io::stdin().read_line(&mut input1).expect("Failed to read line");
let username1 = input1.trim().to_string();
let mut input2 = String::new();
std::io::stdin().read_line(&mut input2).expect("Failed to read line");
let nickname1 = input2.trim().to_string();
let mut input3 = String::new();
std::io::stdin().read_line(&mut input3).expect("Failed to read line");
let username2 = input3.trim().to_string();
// TODO: أنشئ الملف الشخصي الأول باستخدام username1 و nickname1 (Some)
// TODO: Create second profile with username2 and no nickname (None)
// TODO: Print display_name and formatted_nickname for first profile
// Use {:?} for formatted_nickname since it returns an Option
// TODO: Print display_name and formatted_nickname for second profile
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائطتدرّب بنفسك: مترجم Rust عبر الإنترنت