التنفيذات الافتراضية
جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 31 من 61.
حتى الآن، كانت كل method في trait التي عرّفناها مجرد توقيع: متطلبًا بلا جسم. ولكن ماذا لو كانت معظم الأنواع التي تنفّذ trait ستستخدم المنطق نفسه؟ تتيح لك Rust توفير default implementation مباشرةً في تعريف trait.
بدلًا من إنهاء توقيع method بفاصلة منقوطة، تضيف جسمًا:
trait Greet {
fn greet(&self) -> String {
String::from("Hello there!")
}
}
الآن يحصل أي نوع يطبّق Greet تلقائيًا على هذه method، من دون كتابة أي كود داخل block impl:
struct Guest;
impl Greet for Guest {}
let visitor = Guest;
println!("{}", visitor.greet()); // مرحباً هناك!
إن impl Greet for Guest {} empty صالح لأن السمة توفّر السلوك بالفعل. تختار البنية ببساطة الاشتراك في السمة وتحصل على method default مجانًا.
يكون هذا النمط مفيدًا عندما تريد Define سلوك مشترك يعمل في معظم الحالات. يمكن للأنواع التي تحتاج إلى شيء مختلف تجاوز default (الذي ستتعلّمه لاحقًا)، بينما لا تحتاج الأنواع الراضية عن السلوك القياسي إلى تكرار نفسها.
التحدي
سهللنستكشف قوة default implementations من خلال بناء نظام للإشعارات! ستنشئ trait يوفّر سلوكًا قياسيًا جاهزًا، بحيث يمكن للأنواع تفعيله دون كتابة تعليمات برمجية متكررة.
ستنظّم تعليماتك البرمجية عبر ثلاثة ملفات:
notifiable.rs: عرّف trait عامًاNotifiableمع method هيnotify(&self) -> String، وتحتوي على default implementation. يجب أن تعيد القيمة الافتراضية"You have a new notification!". سيحصل أي نوع يطبّق هذا trait تلقائيًا على هذا السلوك دون الحاجة إلى كتابة أي شيء داخل impl block الخاص به.alerts.rs: أنشئ بنيتين بسيطتين من نوع unit عامتين تطبّقان trait الخاص بك:EmailAlert: تطبّقNotifiableباستخدام impl block فارغ (وتستخدم القيمة الافتراضية)SystemAlert: تطبّق أيضًاNotifiableباستخدام impl block فارغ (وتستخدم القيمة الافتراضية)
main.rs: اجمع الوحدات معًا ووضّح كيف يشترك كلا نوعَي التنبيه في السلوك الافتراضي نفسه. أنشئ مثيلات من البنيتين واستدعِ methodnotifyالخاصة بهما.
في ملفك الرئيسي، أنشئ EmailAlert وSystemAlert، ثم اطبع إشعاراتهما في سطرين منفصلين.
يجب أن يكون الناتج:
You have a new notification!
You have a new notification!لاحظ كيف ينتج كلا النوعين ناتجًا متطابقًا: هذه هي روعة default implementations! لم تحتج أي من البنيتين إلى كتابة أي تعليمات برمجية لـ method notify، ومع ذلك فكلتاهما تتمتعان بسلوك إشعارات يعمل بشكل كامل. في الدرس التالي، ستتعلّم كيفية تجاوز هذه القيم الافتراضية عندما يحتاج نوع ما إلى سلوك مخصّص.
جرّب بنفسك
mod notifiable;
mod alerts;
use notifiable::Notifiable;
use alerts::{EmailAlert, SystemAlert};
fn main() {
// TODO: أنشئ مثيلاً من EmailAlert
// TODO: أنشئ مثيلاً من SystemAlert
// TODO: Print the notification from EmailAlert
// TODO: Print the notification from SystemAlert
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأساليب والسلوك
مقدمة في كتل التنفيذمعامل Selfالأساليب القابلة للتعديلالدوال المرتبطةكتل تنفيذ متعددةتسلسل الأساليبمراجعة - إجراءات المستطيل4مشروع: حيوان أليف افتراضي
تعريف الحيوان الأليفإطعام الحيوان الأليف2التغليف والوحدات البرمجية
أساسيات الوحدات البرمجيةالكلمة المفتاحية Publicالحقول الخاصةدوال Gettersدوال Settersمراجعة - الخزانة الآمنة5الأنواع العامة (Generics)
الـ Structs العامةالـ Methods العامةأنواع عامة متعددةالـ Functions العامةمراجعة - Coordinate Point3التعدادات المتقدمة (Advanced Enums)
التعدادات مع البياناتالأساليب (Methods) في التعداداتمطابقة حالات البياناتمراجعة التعداد Optionملخص - التعداد Shape6تعريف الـ Traits
ما هي الـ Trait؟تنفيذ الـ Traitsالتنفيذات الافتراضيةتجاوز التنفيذات الافتراضيةالـ Traits مع المعاملاتملخص - مشغل الوسائطتدرّب بنفسك: مترجم Rust عبر الإنترنت