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

الـ Structs العامة

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

حتى الآن، كان لكل بنية أنشأتها حقول ذات أنواع محددة وملموسة. تحتوي Pet على اسم من النوع String، بينما تحتوي Rectangle على أبعاد من النوع f64. ولكن ماذا لو أردت إنشاء بنية يمكنها الاحتفاظ بأي نوع من البيانات؟

هنا يأتي دور الأنواع العامة. تتيح لك الأنواع العامة كتابة تعليمات برمجية مرنة وقابلة لإعادة الاستخدام تعمل مع أنواع متعددة. وبدلاً من تثبيت نوع محدد في التعليمات البرمجية، تستخدم عنصراً نائباً، عادةً T، يتم استبداله بنوع ملموس عند استخدام البنية.

إليك بنية تغليف بسيطة يمكنها الاحتفاظ بأي نوع:

struct Wrapper<T> {
    value: T,
}

يُعلن <T> بعد اسم البنية عن معامل نوع عام. داخل البنية، يعمل T كبديل عن أي نوع ستستخدمه فعليًا. عند إنشاء مثيل، يستنتج Rust النوع الفعلي:

let int_wrapper = Wrapper { value: 42 };        // T هو i32
let float_wrapper = Wrapper { value: 3.14 };    // T هو f64
let text_wrapper = Wrapper { value: "hello" };  // T هو &str

كل واحد من هذه الأنواع هو نوع ملموس مختلف، Wrapper<i32> وWrapper<f64> وWrapper<&str>، لكنها جميعًا تشترك في تعريف البنية نفسه. وهذا يلغي الحاجة إلى كتابة بنيات منفصلة باسم IntWrapper وFloatWrapper وStringWrapper تؤدي الوظيفة نفسها تقريبًا.

الحرف T مجرد اصطلاح (اختصارًا لكلمة «النوع»). يمكنك استخدام أي معرّف صالح، لكن T هو المعيار في Rust ومعظم اللغات الأخرى التي تدعم الأنواع العامة.

challenge icon

التحدي

سهل

لنبنِ حاوية generic يمكنها الاحتفاظ بأي نوع من القيم! ستنشئ بنية Container توضّح كيف تجعل الأنواع العامة شيفرتك مرنة وقابلة لإعادة الاستخدام.

ستنظّم شيفرتك عبر ملفين:

  • container.rs: Define بنية generic عامة تُسمّى Container<T> وبها field عام single هو item من النوع T. ينبغي أن تتمكن هذه الحاوية من الاحتفاظ بأي نوع: أعداد صحيحة أو أعداد عشرية أو سلاسل نصية أو أي شيء آخر.
  • main.rs: استورد وحدة الحاوية وأظهر مرونتها من خلال إنشاء حاويات تحتوي على أنواع مختلفة من data. ستنشئ ثلاث حاويات وتعرض ما تحتويه كل واحدة منها.

في ملفك الرئيسي، أنشئ الحاويات التالية:

  1. حاوية تحتوي على قيمة integer (المدخل الأول، بعد تحليله كـ i32)
  2. حاوية تحتوي على قيمة float (المدخل الثاني، بعد تحليله كـ f64)
  3. حاوية تحتوي على string (المدخل الثالث، مع الاحتفاظ به كـ String)

ينبغي أن يعرض خرجك contents كل حاوية بهذا التنسيق:

Integer container: {value}
Float container: {value}
String container: {value}

على سبيل المثال، مع inputs هي 42 و3.14 وhello:

Integer container: 42
Float container: 3.14
String container: hello

لاحظ كيف يعمل تعريف Container<T> نفسه مع الأنواع الثلاثة المختلفة: هذه هي قوة الأنواع العامة!

ستتلقى ثلاثة inputs: قيمة integer، وقيمة float، وقيمة string.

جرّب بنفسك

mod container;

use container::Container;

fn main() {
    // اقرأ المدخلات الثلاثة
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let int_value: i32 = input1.trim().parse().expect("Failed to parse integer");

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let float_value: f64 = input2.trim().parse().expect("Failed to parse float");

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let string_value = input3.trim().to_string();

    // TODO: Create three containers using Container<T>
    // 1. An integer container holding int_value
    // 2. A float container holding float_value
    // 3. A string container holding string_value

    // TODO: اطبع محتويات كل حاوية بالتنسيق المطلوب
    // Integer container: {value}
    // Float container: {value}
    // String container: {value}
}
quiz iconاختبر نفسك

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

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

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