Menu
Coddy logo textTech

סטרים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Rust של Coddy. שיעור 12 מתוך 61.

פעולות getter מאפשרות לקוד חיצוני לקרוא נתונים פרטיים. אבל מה אם צריך לאפשר לו לשנות אותם? כאן נכנסות לתמונה פעולות setter: פעולות ציבוריות שמשנות שדות פרטיים באופן מבוקר.

פעולת set בסיסית מקבלת &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;
    }
}

בניגוד לפונקציות גישה (getters), פונקציות הגדרה (setters) ב-Rust משתמשות בדרך כלל בתחילית set_ כדי לציין בבירור שהן משנות נתונים. הפרמטר &mut self חיוני. הוא מעניק למתודה הרשאה לשנות את השדות של המבנה.

העוצמה האמיתית של פונקציות קביעה היא אימות. במקום לקבל כל ערך באופן עיוור, אפשר לאכוף כללים:

pub fn set_balance(&mut self, amount: f64) {
    if amount >= 0.0 {
        self.balance = amount;
    }
    // ערכים שליליים זוכים להתעלמות ללא הודעה
}

כעת הארנק מגן על עצמו: לא משנה איזה ערך הקוד החיצוני מנסה להגדיר, היתרה לעולם לא יכולה להיות שלילית. זוהי אנקפסולציה בפעולה: המבנה שולט בתנאים הקבועים שלו, והקוד החיצוני פשוט אינו יכול להביא אותו למצב לא תקין.

challenge icon

אתגר

קל

בואו נבנה מערכת תרמוסטט שמדגימה כיצד setters יכולים לאכוף כללים כדי לשמור על תקינות הנתונים. לתרמוסטט שלך תהיה הגדרת טמפרטורה שאפשר לכוונן רק בטווח בטוח.

תיצור שני קבצים כדי לארגן את הקוד שלך:

  • thermostat.rs: הגדר struct בשם Thermostat עם שדה פרטי בשם temperature מסוג (i32). ה-struct צריך להיות ציבורי, אבל השדה יישאר פרטי כדי להגן עליו מפני ערכים לא תקינים. ממש את הדברים הבאים:
    • בנאי new שמקבל טמפרטורה התחלתית
    • getter בשם temperature שמחזיר את הטמפרטורה הנוכחית
    • setter בשם set_temperature שמקבל רק ערכים שבין 10 ל-30 (כולל). אם הערך מחוץ לטווח הזה, הטמפרטורה צריכה להישאר ללא שינוי.
  • main.rs: טען את מודול התרמוסטט, צור תרמוסטט והדגם את האימות של ה-setter על ידי ניסיון להגדיר טמפרטורות שונות והדפסת התוצאה אחרי כל ניסיון.

ה-setter צריך להתעלם בשקט מערכים לא תקינים: בלי הודעות שגיאה, רק להשאיר את הטמפרטורה הנוכחית ללא שינוי כשמנסים להגדיר אותה לערך מחוץ לטווח התקין.

הפלט שלך צריך להיות בפורמט המדויק הבא:

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

לדוגמה, אם יוצרים תרמוסטט בטמפרטורה 20, ואז מנסים להגדיר אותו ל-25 (תקין) ולאחר מכן ל-50 (לא תקין), הפלט יהיה:

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

תקבל שלוש קלטים: הטמפרטורה ההתחלתית, הטמפרטורה הראשונה שתנסה להגדיר והטמפרטורה השנייה שתנסה להגדיר.

נסו בעצמכם

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: נסו להגדיר את הטמפרטורה הראשונה והדפיסו את התוצאה
    // פורמט: "After setting to {attempted_value}: {temperature}"

    // TODO: נסו להגדיר את הטמפרטורה השנייה והדפיסו את התוצאה
    // פורמט: "After setting to {attempted_value}: {temperature}"
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Rust אונליין