تسلسل الأساليب
جزء من قسم Object Oriented Programming في رحلة Rust على Coddy — الدرس 6 من 61.
حتى الآن، قامت أساليبنا القابلة للتغيير بتعديل الهيكل (struct) ولم ترجع شيئاً. ولكن ماذا لو أردنا استدعاء عدة أساليب بشكل متتالٍ على نفس المثيل (instance)؟ من خلال إرجاع مرجع إلى self، فإننا نمكّن تسلسل الأساليب (method chaining) — وهو نمط تتدفق فيه استدعاءات أساليب متعددة معاً في تعبير واحد.
يكمن السر في جعل دوال &mut self الخاصة بك تُرجع &mut Self:
struct Config {
debug: bool,
timeout: u32,
}
impl Config {
fn new() -> Config {
Config { debug: false, timeout: 30 }
}
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
تقوم كل طريقة بتعديل الـ struct، ثم تعيد self—وهو مرجع قابل للتغيير (mutable reference) يعود إلى نفس المثيل. يسمح هذا لاستدعاء الطريقة التالي بمواصلة العمل عليه فوراً:
fn main() {
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
println!("Debug: {}, Timeout: {}", config.debug, config.timeout);
// الناتج: Debug: true, Timeout: 60
}
بدلاً من كتابة ثلاث عبارات منفصلة، نقوم بتكوين كل شيء في سطر واحد سلس. هذا النمط "بأسلوب البناء" (builder-style) مفيد بشكل خاص عند إعداد الكائنات التي تحتوي على العديد من الإعدادات الاختيارية، مما يجعل الكود الخاص بك أكثر إيجازاً وسهولة في القراءة.
التحدي
سهلقم بإنشاء هيكل TextStyle يحتوي على ثلاثة حقول: bold (bool)، و italic (bool)، و size (u32).
أضف كتلة تنفيذ (implementation block) لـ TextStyle تحتوي على ما يلي:
new— دالة مرتبطة (associated function) ترجعTextStyleمع ضبطboldعلىfalse، وitalicعلىfalse، وsizeعلى12set_bold— تأخذ&mut selfوقيمةbool، وتقوم بضبط حقل bold، وترجع&mut Selfللسماح بالتسلسل (chaining)set_italic— تأخذ&mut selfوقيمةbool، وتقوم بضبط حقل italic، وترجع&mut Selfللسماح بالتسلسلset_size— تأخذ&mut selfوقيمةu32، وتقوم بضبط حقل size، وترجع&mut Selfللسماح بالتسلسل
ستتلقى ثلاثة مدخلات:
- السطر الأول: إعداد bold (
trueأوfalse) - السطر الثاني: إعداد italic (
trueأوfalse) - السطر الثالث: حجم الخط (u32)
قم بإنشاء TextStyle قابل للتعديل (mutable) باستخدام new، ثم استخدم تسلسل الدوال (method chaining) لتطبيق الإعدادات الثلاثة في تعبير واحد. اطبع الحالة النهائية بالتنسيق الموضح أدناه.
تنسيق المخرجات المتوقع:
Bold: {bold}, Italic: {italic}, Size: {size}ورقة مرجعية
الأساليب التي تأخذ &mut self يمكنها إرجاع &mut Self لتمكين تسلسل الأساليب (method chaining):
impl Config {
fn set_debug(&mut self, value: bool) -> &mut Self {
self.debug = value;
self
}
fn set_timeout(&mut self, seconds: u32) -> &mut Self {
self.timeout = seconds;
self
}
}
يسمح هذا باستدعاءات متعددة للأساليب في تعبير واحد:
let mut config = Config::new();
config.set_debug(true).set_timeout(60);
يقوم كل أسلوب بتعديل الهيكل (struct) ويعيد مرجعاً قابلاً للتعديل (mutable reference) إلى نفس المثيل، مما يسمح للأسلوب التالي بمواصلة العمل عليه فوراً.
جرّب بنفسك
use std::io;
// TODO: قم بتعريف هيكل TextStyle هنا
// TODO: أضف كتلة التنفيذ (implementation block) لـ TextStyle مع:
// - دالة مرتبطة new()
// - تابع set_bold()
// - تابع set_italic()
// - تابع set_size()
fn main() {
let mut input = String::new();
// قراءة إعداد الخط العريض (bold)
io::stdin().read_line(&mut input).expect("Failed to read line");
let bold: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// قراءة إعداد الخط المائل (italic)
io::stdin().read_line(&mut input).expect("Failed to read line");
let italic: bool = input.trim().parse().expect("Invalid bool");
input.clear();
// قراءة إعداد الحجم (size)
io::stdin().read_line(&mut input).expect("Failed to read line");
let size: u32 = input.trim().parse().expect("Invalid u32");
// TODO: أنشئ TextStyle قابل للتعديل باستخدام new()، ثم استخدم تسلسل التوابع (method chaining)
// لتطبيق جميع الإعدادات الثلاثة في تعبير واحد
// TODO: اطبع النتيجة بالتنسيق التالي: Bold: {bold}, Italic: {italic}, Size: {size}
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس 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 مع المعاملاتملخص - مشغل الوسائط