Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

قيود متعددة

جزء من قسم البرمجة كائنية التوجه في رحلة Rust على Coddy. الدرس 41 من 61.

أحيانًا لا تكون سمة واحدة كافية. قد تحتاج إلى نوع generic يمكنه أن يُطبع و أن يوفّر ملخصًا. تتيح لك Rust طلب سمات متعددة باستخدام الصيغة +.

إليك كيفية تحديد أن نوعًا ما يجب أن يطبّق سمتين:

use std::fmt::Display;

trait Summary {
    fn summarize(&self) -> String;
}

fn announce<T: Display + Summary>(item: T) {
    println!("Breaking news: {}", item);
    println!("Summary: {}", item.summarize());
}

القيد T: Display + Summary يعني "يجب أن يطبّق T كلًّا من Display وSummary." داخل الدالة، يمكنك استخدام القدرات من كلتا السمتين: الطباعة باستخدام {} (من Display) واستدعاء summarize() (من Summary).

يمكنك ربط أي عدد تحتاج إليه من السمات:

fn process<T: Display + Summary + Clone>(item: T) {
    // يمكن الطباعة والتلخيص والاستنساخ
}

هذا النمط أساسي عندما تعتمد function الخاصة بك على سلوكيات متعددة. وبدلاً من قبول أي نوع والأمل في أن يعمل، فإنك تعلن صراحةً عن capabilities المطلوبة بالضبط، ويفرض المترجم ذلك في وقت الترجمة.

challenge icon

التحدي

سهل

لنبنِ نظامًا لفحص المنتجات يتطلب أن تتمتع العناصر بقدرات متعددة! ستنشئ دالة generic لا تقبل إلا الأنواع التي تطبق كلًا من trait مخصص وtrait قياسي، موضحًا كيف تجمع صيغة + بين حدود متعددة.

ستنظم الكود الخاص بك عبر ملفين:

  • product.rs: Define trait عامًا باسم Inspectable مع method تسمى inspect تأخذ &self وتُرجع String تحتوي على تفاصيل الفحص. ثم أنشئ struct عامًا باسم Gadget مع الحقلين العامين name (String) وserial (u32). يجب أن يطبق Gadget كلًا من Inspectable (مع إرجاع Inspecting: {name}) وstd::fmt::Display (مع التنسيق بالشكل {name} (SN: {serial})). وأخيرًا، أنشئ دالة generic عامة تسمى full_report تقبل أي نوع T يطبق كلًا من Display وInspectable. يجب أن تطبع هذه الدالة سطرين: العنصر أولًا باستخدام منسق {}، ثم نتيجة استدعاء inspect().
  • main.rs: استورد module الخاص بالمنتج وأنشئ instance من Gadget باستخدام inputs المقدمة. استدعِ full_report مع gadget الخاص بك لإظهار أنه يستوفي متطلبات trait كليهما.

تكمن قوة الحدود المتعددة في أن دالة full_report الخاصة بك يمكنها استخدام capabilities من كلا traitين، فتعرض العنصر بطريقة أنيقة وتحصل أيضًا على تفاصيل الفحص، وكل ذلك مضمون أثناء compile time.

يجب أن يُظهر output كلاً من تنسيق العرض ونتيجة الفحص:

{name} (SN: {serial})
Inspecting: {name}

على سبيل المثال، مع inputs Smartwatch و98765:

Smartwatch (SN: 98765)
Inspecting: Smartwatch

ستتلقى inputين: اسم gadget ورقم serial (قم بتحليله كـ u32).

REQUIRED OUTPUT FORMAT: [Your translated content here]

جرّب بنفسك

mod product;

use product::{Gadget, full_report};

fn main() {
    // اقرأ المدخلات
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Failed to read line");
    let name = name.trim().to_string();
    
    let mut serial_input = String::new();
    std::io::stdin().read_line(&mut serial_input).expect("Failed to read line");
    let serial: u32 = serial_input.trim().parse().expect("Failed to parse serial");
    
    // TODO: أنشئ مثيل Gadget بالاسم والرقم التسلسلي
    
    // TODO: استدعِ full_report مع الـ gadget الخاص بك
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: مترجم Rust عبر الإنترنت