1.1 - כלי עבודה והבנת אבחוני המהדר - פתרון
פתרון אבחון בעלות ותוצר בנייה¶
הערך task נוצר בבעלות main. החתימה של announce מקבלת String בבעלות, ולכן הקריאה מעבירה את הערך. ההדפסה המאוחרת מנסה להשתמש בערך דרך המשתנה שממנו הוא כבר הועבר.
בתיקון של השאלה נקבל מבט לטקסט:
fn announce(label: &str) {
println!("running {label}");
}
fn main() {
let task = String::from("scan");
announce(&task);
println!("finished {task}");
}
הבעלות לא עברה לפונקציה. בסיום הקריאה מותר להמשיך להשתמש במחרוזת, משום שהפונקציה רק קראה ממנה בזמן ההשאלה.
בתיקון של שכפול נשמור את החתימה ונעביר עותק:
fn announce(label: String) {
println!("running {label}");
}
fn main() {
let task = String::from("scan");
announce(task.clone());
println!("finished {task}");
}
כעת יש שני ערכים עצמאיים. הפונקציה משמידה את העותק שקיבלה, והמקור נשאר חי ב־main. הפונקציה הנוכחית רק מדפיסה, ולכן אין סיבה תפקודית לשכפול. פונקציה ששומרת את הטקסט בבעלותה אחרי סיום הקריאה הייתה מציבה דרישה אחרת.
לאחר cargo build, הפקודה ./target/debug/diagnostic_lab מריצה את התוצר הקיים. שינוי בקובץ המקור לבדו אינו משנה את הבינארי. לכן הרצה ישירה לפני בנייה נוספת מציגה את ההודעה הישנה, ואילו cargo run בונה מחדש כאשר צריך ואז מציגה את ההודעה החדשה.
שימו לב שלא בדקנו כאן ביצועים. מהקוד אפשר להסיק שקיים שכפול מפורש של המחרוזת, אך טענה מספרית על המחיר שלו דורשת ניסוי מתאים. גם הצלחת הבנייה אינה מחליפה בדיקת התנהגות של התוכנית.