trait
السمات trait
trait يعرّف سلوكًا مشتركًا يمكن لأنواع مختلفة تنفيذه، وهو بديل Rust عن الواجهات (interfaces) في لغات أخرى.
السمة (trait) تصف مجموعة توابع يجب أن يوفّرها أي نوع ينفّذها، وقد توفّر تنفيذًا افتراضيًا لبعضها. تُستخدم السمات كقيود على الأنواع العامّة (Generics) لضمان أن النوع يوفّر سلوكًا معيّنًا، أو كأساس للإرسال الديناميكي عبر dyn Trait.
مكتبة Rust القياسية مليئة بسمات جاهزة يمكن اشتقاقها تلقائيًا بـ derive مثل Debug وClone وPartialEq، بدل كتابتها يدويًا.
الصياغة
trait Name {
fn method(&self) -> T;
fn default_method(&self) -> T { ... }
}📄 مثال
trait Summary {
fn summarize(&self) -> String;
fn preview(&self) -> String {
format!("معاينة: {}", self.summarize())
}
}
struct Article { title: String }
impl Summary for Article {
fn summarize(&self) -> String {
self.title.clone()
}
}أهم النقاط
| العنصر | الوظيفة |
|---|---|
| fn method(&self); | توقيع إلزامي — كل نوع منفّذ يجب أن يكتبه |
| fn m(&self) { ... } | تنفيذ افتراضي — يمكن تجاوزه أو تركه كما هو |
| T: TraitName | قيد على Generic يفرض تنفيذ السمة |
| dyn TraitName | استخدام السمة ككائن سمة للإرسال الديناميكي |
💡 نصائح عملية
- استخدم trait كقيد على Generics (T: Summary) بدل dyn Trait عندما تعرف النوع وقت الترجمة — أداء أفضل
- استفد من derive للسمات الشائعة (Debug, Clone, PartialEq) بدل تنفيذها يدويًا
⚠️ أخطاء شائعة
- محاولة استخدام سمة كنوع إرجاع مباشر (fn f() -> Summary) — يجب تغليفها بـ Box<dyn Trait> أو استخدام impl Trait
- نسيان استيراد السمة (use) قبل استدعاء توابعها على نوع ينفّذها في وحدة أخرى
خصائص ذات صلة
🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار RUST الكامل بالعربي.