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

دوال Setters

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

تسمح Getters للتعليمات البرمجية الخارجية بأن read البيانات private. لكن ماذا لو احتجت إلى السماح لها بتغييرها؟ هنا يأتي دور setter methods: وهي أساليب عامة تعدّل حقول private بطريقة مُتحكَّم بها.

يتلقى setter أساسي &mut self وقيمة جديدة:

// wallet.rs
pub struct Wallet {
    balance: f64,
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Self { balance: initial }
    }
    
    pub fn balance(&self) -> f64 {
        self.balance
    }
    
    pub fn set_balance(&mut self, amount: f64) {
        self.balance = amount;
    }
}

على عكس دوال getter، تستخدم دوال setter في Rust عادةً البادئة set_ للإشارة بوضوح إلى أنها تعدّل البيانات. وتُعدّ المعلمة &mut self ضرورية. فهي تمنح الطريقة الإذن بتغيير حقول البنية.

تكمن القوة الحقيقية لـ أدوات الضبط في التحقق. فبدلاً من قبول أي قيمة بشكل أعمى، يمكنك فرض قواعد:

pub fn set_balance(&mut self, amount: f64) {
    if amount >= 0.0 {
        self.balance = amount;
    }
    // يتم تجاهل القيم السالبة بصمت
}

الآن تحمي المحفظة نفسها: بغضّ النظر عن القيمة التي يحاول الكود الخارجي تعيينها، لا يمكن أن يصبح balance سالبًا أبدًا. هذا هو التغليف عمليًا: تتحكم البنية في ثوابتها، ولا يستطيع الكود الخارجي ببساطة وضعها في حالة غير صالحة.

challenge icon

التحدي

سهل

لنبنِ نظام ترموستات يوضّح كيف يمكن لـ setters فرض قواعد للحفاظ على صحة البيانات. سيحتوي الترموستات على إعداد لدرجة الحرارة لا يمكن تعديله إلا ضمن نطاق آمن.

ستنشىء ملفين لتنظيم التعليمات البرمجية:

  • thermostat.rs: Define بنية Thermostat مع حقل temperature private من النوع (i32). يجب أن تكون البنية public، لكن يجب أن يبقى الحقل private لحمايته من القيم غير الصالحة. Implement:
    • منشئ new يأخذ درجة حرارة initial
    • getter باسم temperature يعيد درجة الحرارة current
    • setter باسم set_temperature لا يقبل إلا القيم between 10 و30 (inclusive). إذا كانت القيمة outside هذا النطاق، فيجب أن تبقى درجة الحرارة دون تغيير.
  • main.rs: أضف وحدة الترموستات، وأنشئ ترموستات، وأظهر عملية التحقق التي يجريها setter من خلال محاولة ضبط درجات حرارة مختلفة وطباعة result بعد كل Attempt.

يجب أن يتجاهل setter القيم غير الصالحة بصمت: لا توجد رسائل خطأ، بل keep درجة الحرارة current دون تغيير عندما يحاول شخص ضبطها إلى قيمة outside النطاق الصالح.

يجب أن يتبع output هذا التنسيق الدقيق:

Initial: {temperature}
After setting to {attempted_value}: {temperature}
After setting to {attempted_value}: {temperature}

على سبيل المثال، إذا أنشأت ترموستات عند 20، ثم حاولت ضبطه على 25 (صالحة)، وبعد ذلك على 50 (غير صالحة)، فسيكون output كما يلي:

Initial: 20
After setting to 25: 25
After setting to 50: 25

ستتلقى ثلاثة inputs: درجة الحرارة initial، ودرجة الحرارة first التي ستجري محاولة ضبطها، ودرجة الحرارة second التي ستجري محاولة ضبطها.

جرّب بنفسك

mod thermostat;

use thermostat::Thermostat;

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

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

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

    // TODO: أنشئ ترموستات بدرجة الحرارة الأولية

    // TODO: اطبع درجة الحرارة الأولية
    // التنسيق: "Initial: {temperature}"

    // TODO: حاول تعيين درجة الحرارة الأولى واطبع النتيجة
    // Format: "After setting to {attempted_value}: {temperature}"

    // TODO: حاول تعيين درجة الحرارة الثانية واطبع النتيجة
    // Format: "After setting to {attempted_value}: {temperature}"
}
quiz iconاختبر نفسك

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

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

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