שדות פרטיים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Rust של Coddy. שיעור 10 מתוך 61.
בשיעור הקודם הפכת הכול לציבורי: את המבנה, את השדות שלו ואת המתודות שלו. אבל אנקפסולציה אמיתית פירושה לשלוט באופן שבו ניתן לגשת לנתונים שלך. ב-Rust, אפשר להפוך מבנה לציבורי ולהשאיר את השדות שלו פרטיים.
נבחן Wallet שאמור לעולם לא להיות בעל יתרה שלילית. אם השדה ציבורי, כל אחד יכול להגדיר לו כל ערך:
// wallet.rs
pub struct Wallet {
balance: f64, // בלי pub = פרטי!
}
impl Wallet {
pub fn new(initial: f64) -> Wallet {
Wallet { balance: initial }
}
}
שימו לב ש־Wallet ציבורי, אבל למילת המפתח pub אין שימוש ב־balance. פירוש הדבר הוא שקוד מחוץ למודול יכול ליצור Wallet באמצעות הבנאי, אך אינו יכול לקרוא את שדה היתרה או לשנות אותו ישירות:
// main.rs
mod wallet;
use wallet::Wallet;
fn main() {
let w = Wallet::new(100.0);
// println!("{}", w.balance); // שגיאה! השדה פרטי
// w.balance = -50.0; // שגיאה! אי אפשר לגשת לשדה פרטי
}
זהו הבסיס של כימוס: המבנה שולט בנתונים שלו. קוד חיצוני חייב לעבור דרך המתודות שאתה מספק, כך שתוכל להוסיף אימות, רישום ביומן או כל לוגיקה אחרת. הנתונים נשארים מוגנים מפני מצבים לא תקינים.
בשיעורים הבאים תלמד איך לספק גישה מבוקרת לנתונים הפרטיים האלה באמצעות מתודות getter ו-setter.
אתגר
קלבואו נבנה מערכת חיישן טמפרטורה שמדגימה כימוס באמצעות הגנה על נתונים רגישים בתוך מודול.
תיצרו שני קבצים כדי לארגן את הקוד שלכם:
sensor.rs: הגדירו מבנהTemperatureSensorעם שני שדות:location(String) ו-reading(f64). המבנה צריך להיות ציבורי כדי שיהיה אפשר להשתמש בו מקבצים אחרים, אבל השאירו את שני השדות פרטיים: קוד חיצוני לא אמור להיות מסוגל לגשת ישירות לנתוני החיישן או לשנות אותם. הוסיפו בנאי ציבורי בשםnewשמקבל שם של מיקום וקריאת טמפרטורה התחלתית.main.rs: ייבאו את מודול החיישן שלכם וצרוTemperatureSensorבאמצעות הבנאי. מכיוון שהשדות פרטיים, לא תוכלו להדפיס אותם ישירות; במקום זאת, הדפיסו הודעת אישור שמציינת שהחיישן נוצר בהצלחה.
האתגר הזה מתמקד בעיקרון המרכזי של שדות פרטיים: אפשר לגשת למבנה, אבל הנתונים הפנימיים שלו מוגנים. קוד חיצוני יכול ליצור קשר עם החיישן רק באמצעות המתודות שאתם מספקים (במקרה הזה, הבנאי בלבד).
הפלט שלכם צריך להיות בדיוק בפורמט הבא:
Sensor created for: {location}כדי לגשת למיקום לצורך ההדפסה, תצטרכו לגרום לפונקציה new להדפיס את ההודעה הזאת לפני שהיא מחזירה את החיישן, מכיוון שהשדה עצמו פרטי.
לדוגמה, אם תיצרו חיישן עם המיקום "Kitchen" והקריאה 22.5, הפלט יהיה:
Sensor created for: Kitchenתקבלו שתי כניסות: שם המיקום וקריאת הטמפרטורה ההתחלתית.
נסו בעצמכם
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 תטפל בהדפסת הודעת האישור
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מתודות והתנהגות
מבוא לבלוקי מימושהפרמטר selfמתודות ניתנות לשינויפונקציות משויכותבלוקי מימוש מרוביםשרשור מתודותסיכום – פעולות מלבן4פרויקט: חיית מחמד וירטואלית
הגדרת חיית המחמדהאכלת חיית המחמדתרגלו בעצמכם: קומפיילר Rust אונליין