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

الـ Methods العامة

جزء من قسم Object Oriented Programming في رحلة Rust على Coddy — الدرس 25 من 61.

يمكن لبنية عامة (generic struct) أن تحتوي على أي نوع، ولكنها ليست مفيدة جداً بدون دوال (methods) للتفاعل مع بياناتها. لتعريف دوال لبنية عامة، تحتاج إلى صيغة خاصة في كتلة impl.

يكمن السر في التصريح عن المعلمة العامة (generic parameter) في الـ impl نفسه:

struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    fn get(&self) -> &T {
        &self.value
    }
}

لاحظ وجود impl<T> قبل Wrapper<T>. هذا يخبر Rust أن T هو معلمة نوع عامة (generic type parameter) لكامل كتلة التنفيذ (implementation block). بدون هذا التصريح، ستبحث Rust عن نوع ملموس (concrete type) باسم T وستفشل في العثور عليه.

تعيد الطريقة get القيمة &T—وهي مرجع لأي نوع يحتويه الغلاف (wrapper). يعمل هذا سواء كان T عدداً صحيحاً، أو سلسلة نصية، أو أي نوع آخر:

let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };

println!("{}", num_wrapper.get());  // 100
println!("{}", text_wrapper.get()); // Rust

يعمل تعريف الطريقة نفسه لكليهما، لأن الـ T العام يتكيف مع كل نوع محدد في وقت التجميع.

challenge icon

التحدي

سهل

دعنا نوسع الحاوية العامة (generic container) الخاصة بك باستخدام الدوال (methods)! ستقوم ببناء هيكل Box (لا تخلط بينه وبين Box القياسي في Rust) يمكنه الاحتفاظ بأي نوع ويوفر دوال للتفاعل مع محتوياته.

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

  • mybox.rs: قم بتعريف هيكل عام عام (public generic struct) يسمى MyBox<T> مع حقل خاص contents من النوع T. قم بتنفيذ الدوال لهذا الهيكل:
    • دالة مرتبطة (associated function) تسمى new تقوم بإنشاء MyBox جديد بالقيمة المعطاة.
    • دالة peek تعيد مرجعاً (reference) للمحتويات (باستخدام &self).
    • دالة replace تأخذ قيمة جديدة وتستبدل المحتويات الحالية (باستخدام &mut self).
  • main.rs: قم باستيراد الوحدة (module) الخاصة بك واستعرض الدوال العامة وهي تعمل مع أنواع مختلفة. ستقوم بإنشاء صناديق (boxes)، ومعاينة محتوياتها، واستبدال القيم لإظهار الدوال قيد التشغيل.

تذكر الصيغة الأساسية لتنفيذ الدوال على هيكل عام: تحتاج إلى impl<T> قبل MyBox<T> لإخبار Rust أن T هو بارامتر عام (generic parameter) لكامل كتلة التنفيذ.

في ملفك الرئيسي، قم باستعراض MyBox الخاص بك عن طريق:

  1. إنشاء صندوق يحتوي على عدد صحيح (المدخل الأول، يتم تحليله كـ i32).
  2. معاينة محتوياته وطباعة القيمة.
  3. استبدال المحتويات بعدد صحيح جديد (المدخل الثاني، يتم تحليله كـ i32).
  4. المعاينة مرة أخرى لإظهار القيمة المحدثة.
  5. إنشاء صندوق ثاني يحتوي على سلسلة نصية (المدخل الثالث).
  6. معاينة محتويات صندوق السلسلة النصية.

يجب أن يتبع مخرجك هذا التنسيق:

Integer box contains: {value}
After replace: {value}
String box contains: {value}

على سبيل المثال، مع المدخلات 10، و 25، و Rust:

Integer box contains: 10
After replace: 25
String box contains: Rust

ستتلقى ثلاثة مدخلات: عدد صحيح أولي، وعدد صحيح بديل، وقيمة نصية.

ورقة مرجعية

لتعريف دوال (methods) لهيكل بيانات عام (generic struct)، قم بالتصريح عن المعامل العام في كتلة الـ impl:

struct Wrapper<T> {
    value: T,
}

impl<T> Wrapper<T> {
    fn get(&self) -> &T {
        &self.value
    }
}

تخبر صيغة impl<T> لغة Rust أن T هو معامل نوع عام (generic type parameter) لكتلة التنفيذ بأكملها. بدون ذلك، ستبحث Rust عن نوع ملموس (concrete type) باسم T.

يمكن للدوال أن تعيد مراجع للنوع العام (&T)، وهو ما يعمل مع أي نوع ملموس:

let num_wrapper = Wrapper { value: 100 };
let text_wrapper = Wrapper { value: "Rust" };

println!("{}", num_wrapper.get());  // 100
println!("{}", text_wrapper.get()); // Rust

جرّب بنفسك

mod mybox;

use mybox::MyBox;

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

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let replacement_int: i32 = input2.trim().parse().expect("Invalid integer");

    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: مع العدد الصحيح الأولي MyBox قم بإنشاء
    
    // TODO: "Integer box contains: {value}" :ألقِ نظرة على محتوياته واطبع
    
    // TODO: استبدل المحتويات بالعدد الصحيح البديل
    
    // TODO: "After replace: {value}" :ألقِ نظرة مرة أخرى واطبع
    
    // TODO: مع قيمة السلسلة النصية MyBox قم بإنشاء صندوق ثانٍ من نوع
    
    // TODO: "String box contains: {value}" :ألقِ نظرة على صندوق السلسلة النصية واطبع
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming