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

الأساليب القابلة للتعديل

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

تحتاج الدوال (methods) أحيانًا إلى القيام بما هو أكثر من مجرد قراءة البيانات—فهي تحتاج إلى تغييرها. لإنشاء دوال يمكنها تعديل حقول الـ struct، نستخدم &mut self بدلاً من &self.

تشير الكلمة المفتاحية mut إلى استعارة قابلة للتغيير (mutable borrow)، مما يمنح الدالة الإذن لتعديل الحالة الداخلية للمثيل (instance):

struct Counter {
    value: i32,
}

impl Counter {
    fn increment(&mut self) {
        self.value += 1;
    }
    
    fn decrement(&mut self) {
        self.value -= 1;
    }
    
    fn get(&self) -> i32 {
        self.value
    }
}

لاحظ أن increment و decrement يستخدمان &mut self لأنهما يقومان بتعديل value، بينما يستخدم get الـ &self بما أنه يقرأ البيانات فقط.

عند استدعاء الطرق القابلة للتغيير (mutable methods)، يجب التصريح عن المثيل (instance) نفسه كقابل للتغيير:

fn main() {
    let mut counter = Counter { value: 0 };
    
    counter.increment();
    counter.increment();
    println!("{}", counter.get()); // 2
    
    counter.decrement();
    println!("{}", counter.get()); // 1
}

إذا نسيت الكلمة المفتاحية mut عند إنشاء المثيل (instance)، ستمنعك لغة Rust من استدعاء أي من دوال &mut self عليه. يضمن ذلك أنك دائماً على دراية متى قد تتغير بياناتك.

challenge icon

التحدي

سهل

أنشئ هيكل BankAccount بحقل واحد: balance (i32).

أضف كتلة تنفيذ لـ BankAccount بثلاث دوال:

  • deposit — تأخذ &mut self و amount: i32، وتضيف المبلغ إلى الرصيد
  • withdraw — تأخذ &mut self و amount: i32، وتطرح المبلغ من الرصيد
  • get_balance — تأخذ &self وتعيد الرصيد الحالي كـ i32

ستتلقى ثلاثة مدخلات:

  • السطر الأول: الرصيد الأولي (i32)
  • السطر الثاني: مبلغ الإيداع (i32)
  • السطر الثالث: مبلغ السحب (i32)

أنشئ مثيلاً قابلاً للتغيير من BankAccount بالرصيد الأولي، ثم قم بإيداع المبلغ المحدد، وسحب المبلغ المحدد، واطبع الرصيد النهائي.

تنسيق المخرجات المتوقع:

{final_balance}

ورقة مرجعية

تستخدم الطرق (Methods) التي تعدل حقول الهيكل (struct fields) الرمز &mut self (استعارة قابلة للتغيير)، بينما تستخدم الطرق التي تقرأ البيانات فقط الرمز &self:

struct Counter {
    value: i32,
}

impl Counter {
    fn increment(&mut self) {
        self.value += 1;
    }
    
    fn decrement(&mut self) {
        self.value -= 1;
    }
    
    fn get(&self) -> i32 {
        self.value
    }
}

لاستدعاء الطرق القابلة للتغيير، يجب التصريح عن الكائن (instance) كقابل للتغيير باستخدام let mut:

let mut counter = Counter { value: 0 };

counter.increment();
counter.increment();
println!("{}", counter.get()); // 2

counter.decrement();
println!("{}", counter.get()); // 1

بدون الكلمة المفتاحية mut في الكائن، ستمنع لغة Rust استدعاء أي طرق &mut self.

جرّب بنفسك

use std::io;

// TODO: قم بتعريف هيكل BankAccount هنا


// TODO: أضف كتلة التنفيذ لـ BankAccount مع دوال deposit و withdraw و get_balance


fn main() {
    let mut input = String::new();
    
    // قراءة الرصيد الأولي
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let initial_balance: i32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    
    // قراءة مبلغ الإيداع
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let deposit_amount: i32 = input.trim().parse().expect("Invalid number");
    
    input.clear();
    
    // قراءة مبلغ السحب
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let withdraw_amount: i32 = input.trim().parse().expect("Invalid number");
    
    // TODO: قم بإنشاء مثيل قابل للتعديل من BankAccount مع initial_balance
    // TODO: قم باستدعاء deposit مع deposit_amount
    // TODO: قم باستدعاء withdraw مع withdraw_amount
    // TODO: قم بطباعة الرصيد النهائي باستخدام get_balance
}
quiz iconاختبر نفسك

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

جميع دروس Object Oriented Programming