ה-trait Drop
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Rust של Coddy. שיעור 56 מתוך 61.
כאשר ערך יוצא מתחום החיים שלו ב-Rust, הוא מנוקה באופן אוטומטי. אבל מה אם צריך להריץ קוד מותאם אישית באותו רגע, למשל לרשום ביומן, לשחרר משאב או לשלוח הודעה אחרונה? ה-trait Drop מאפשר לך להגדיר בדיוק מה קורה כאשר ה-struct שלך עומד להיהרס.
לתכונה Drop יש מתודה אחת בשם drop שמקבלת &mut self:
struct Connection {
id: u32,
}
impl Drop for Connection {
fn drop(&mut self) {
println!("Connection {} closed.", self.id);
}
}
אף פעם לא קוראים ישירות ל-drop: Rust קוראת לה אוטומטית כשהערך יוצא מהתחום:
fn main() {
let conn = Connection { id: 42 };
println!("Using connection...");
} // "Connection 42 closed." מודפס כאן אוטומטית
הפלט יהיה:
Using connection...
Connection 42 closed.
זו הגרסה של Rust למחסל. מקובל להשתמש בו למשימות ניקוי: סגירת מתארי קבצים, התנתקות משרתים או שחרור משאבים ש-Rust לא יכולה לנהל באופן אוטומטי. ה-trait Drop מבטיח שקוד הניקוי שלך יופעל, גם אם תחום החיים מסתיים בגלל החזרה מוקדמת.
אתגר
קלבואו נבנה מערכת לניהול משאבים שמדגימה ניקוי אוטומטי! תיצרו struct בשם FileHandle שמדמה פתיחה וסגירה של קבצים. כשה-handle יוצא מהתחום שלו, הוא יודיע באופן אוטומטי שהקובץ נסגר.
תארגנו את הקוד שלכם בשני קבצים:
file_handle.rs: הגדירו struct ציבורי בשםFileHandleעם שדה ציבורי בשםfilename(String). ממשו פונקציה משויכת בשםnewשיוצרת FileHandle ומדפיסה הודעה כשהקובץ "opened". לאחר מכן, ממשו את ה-trait בשםDrop, כך שכאשר ה-handle מושמט, תודפס הודעה על סגירת הקובץ.main.rs: ייבאו את המודול file_handle שלכם וצרו פונקציה בשםprocess_fileשמקבלת filename, יוצרת FileHandle בתוך תחום מקומי ומדפיסה הודעת עיבוד בזמן שהקובץ "open". המימוש של Drop יפעל אוטומטית כשהתחום יסתיים. קראו לפונקציה עם הקלט שסופק.
כשיוצרים FileHandle, הוא אמור להדפיס:
Opening file: {filename}בזמן העיבוד (בתוך התחום), הדפיסו:
Processing {filename}...כשמשמיטים את FileHandle (התחום מסתיים), הוא אמור להדפיס:
Closing file: {filename}לדוגמה, עבור הקלט data.txt:
Opening file: data.txt
Processing data.txt...
Closing file: data.txtועבור הקלט config.json:
Opening file: config.json
Processing config.json...
Closing file: config.jsonתקבלו קלט אחד: מחרוזת שם הקובץ.
נסו בעצמכם
mod file_handle;
use file_handle::FileHandle;
// TODO: יש לממש את הפונקציה process_file
// עליה לבצע את הפעולות הבאות:
// 1. ליצור תחום מקומי (באמצעות סוגריים מסולסלים {})
// 2. בתוך התחום הזה, ליצור FileHandle באמצעות FileHandle::new()
// 3. להדפיס את הודעת העיבוד: "Processing {filename}..."
// 4. כאשר התחום מסתיים, Drop ייקרא אוטומטית
fn process_file(filename: &str) {
// TODO: יש לממש את הפונקציה הזו
}
fn main() {
let mut input = String::new();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let filename = input.trim();
process_file(filename);
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מתודות והתנהגות
מבוא לבלוקי מימושהפרמטר selfמתודות ניתנות לשינויפונקציות משויכותבלוקי מימוש מרוביםשרשור מתודותסיכום – פעולות מלבן4פרויקט: חיית מחמד וירטואלית
הגדרת חיית המחמדהאכלת חיית המחמדתרגלו בעצמכם: קומפיילר Rust אונליין