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

الحقول الخاصة

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

في الدرس السابق، جعلت كل شيء public: الـ struct، وfield الخاصة به، وطرقه. لكن التغليف الحقيقي يعني التحكم في كيفية access بياناتك. في Rust، يمكنك جعل struct عامًا مع إبقاء field الخاصة به private.

تخيّل Wallet الذي يجب ألّا يكون له balance سالبًا على الإطلاق. إذا كان fieldpublic، فبإمكان أي شخص تعيين أي قيمة له:

// wallet.rs
pub struct Wallet {
    balance: f64,  // بدون pub = خاص!
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Wallet { balance: initial }
    }
}

لاحظ أن Wallet عام، لكن balance لا يحتوي على الكلمة المفتاحية pub. هذا يعني أن الشيفرة الموجودة خارج الوحدة يمكنها إنشاء Wallet باستخدام constructor، لكنها لا تستطيع قراءة حقل balance أو تعديله مباشرةً:

// main.rs
mod wallet;
use wallet::Wallet;

fn main() {
    let w = Wallet::new(100.0);
    // println!("{}", w.balance);  // خطأ! الحقل خاص
    // w.balance = -50.0;          // خطأ! لا يمكن الوصول إلى الحقل الخاص
}

هذا هو أساس التغليف: يتحكم struct في بياناته الخاصة. يجب على التعليمات البرمجية الخارجية المرور عبر الأساليب التي توفرها، ما يعني أنه يمكنك إضافة التحقق أو التسجيل أو أي منطق آخر. تظل البيانات محمية من الحالات غير الصالحة.

في الدروس القادمة، ستتعلّم كيفية توفير access مُتحكَّم به إلى هذه البيانات private من خلال أساليب getter وsetter.

challenge icon

التحدي

سهل

لنبنِ نظام sensor لدرجة الحرارة يوضّح التغليف من خلال إبقاء البيانات الحساسة محمية داخل وحدة.

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

  • sensor.rs: عرّف TemperatureSensor struct مع fieldين: location (String) وreading (f64). يجب أن تكون البنية public حتى يمكن استخدامها من ملفات أخرى، لكن أبقِ كلا fieldين private: يجب ألا تتمكن التعليمات البرمجية الخارجية من access بيانات sensor أو تعديلها مباشرةً. أضف constructor ‏new public يأخذ اسم location وقراءة درجة حرارة initial.
  • main.rs: أدرِج وحدة sensor وأنشئ TemperatureSensor using constructor. بما أن fieldين private، لن تتمكن من طباعتهما مباشرةً؛ وبدلاً من ذلك، اطبع confirmation message تُظهر أن sensor تم created بنجاح.

يركّز هذا التحدي على المفهوم الأساسي للحقول private: إن struct متاح، لكن بياناته الداخلية محمية. لا يمكن للتعليمات البرمجية الخارجية التفاعل مع sensor إلا من خلال الأساليب التي توفرها (في هذه الحالة، constructor فقط).

يجب أن يتبع ناتجك هذا التنسيق exact:

Sensor created for: {location}

للوصول إلى location بغرض طباعته، ستحتاج إلى جعل دالة new تطبع هذه الرسالة قبل إرجاع sensor، لأن field نفسه private.

على سبيل المثال، إذا أنشأت sensor باستخدام location ‏"Kitchen" وreading ‏22.5، فسيكون الناتج:

Sensor created for: Kitchen

ستتلقى مدخلين: اسم location وreading درجة الحرارة initial.

جرّب بنفسك

mod sensor;

use sensor::TemperatureSensor;

fn main() {
    // اقرأ الإدخال
    let mut location = String::new();
    std::io::stdin().read_line(&mut location).expect("Failed to read line");
    let location = location.trim().to_string();
    
    let mut reading_str = String::new();
    std::io::stdin().read_line(&mut reading_str).expect("Failed to read line");
    let reading: f64 = reading_str.trim().parse().expect("Failed to parse reading");
    
    // TODO: أنشئ TemperatureSensor باستخدام المُنشئ
    // ستتولى الدالة new طباعة رسالة التأكيد
    
}
quiz iconاختبر نفسك

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

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

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