הרכבה
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Rust של Coddy. שיעור 55 מתוך 61.
שפות רבות מונחות עצמים מסתמכות במידה רבה על ירושה כדי לשתף פונקציונליות בין טיפוסים. Rust נוקטת גישה אחרת: הרכבה. במקום לרשת התנהגות ממחלקת אב, בונים טיפוסים מורכבים באמצעות הכללת טיפוסים אחרים כשדות.
נבחן מידול של מכונית. במקום ליצור מחלקת בסיס Vehicle ולרשת ממנה, מרכיבים Car מרכיבים קטנים וממוקדים:
struct Engine {
horsepower: u32,
}
struct Wheels {
count: u8,
diameter: f32,
}
struct Car {
engine: Engine,
wheels: Wheels,
brand: String,
}
הCar לא יורשת מ־Engine או מ־Wheels. יש לה אותם. קשר מסוג "יש-לו" הוא הרכבה. אפשר לגשת לרכיבים הפנימיים דרך השדות שלהם ולקרוא ישירות למתודות שלהם:
impl Engine {
fn start(&self) {
println!("Engine with {} HP started!", self.horsepower);
}
}
impl Car {
fn start(&self) {
self.engine.start(); // האצל את הפעולה לרכיב הפנימי
}
}
התבנית הזו שומרת על כך שכל מבנה מתמקד באחריות יחידה. צריך לשנות את אופן הפעולה של מנועים? יש לשנות רק את המבנה Engine. רוצים לעשות שימוש חוזר ב־Wheels עבור אופנוע? פשוט כוללים אותו במבנה חדש. הרכבה מעניקה גמישות ללא הצימוד ההדוק שירושה יוצרת לעיתים קרובות.
אתגר
קלבואו נבנה מערכת מחשב באמצעות הרכבה! במקום ליצור מבנה ענק אחד, תרכיבו Computer מרכיבים קטנים וממוקדים יותר: CPU ו-Memory. כל רכיב ידע לתאר את עצמו, והמחשב יעביר את האחריות לחלקיו.
תארגנו את הקוד שלכם בשלושה קבצים:
cpu.rs: הגדירו מבנה ציבורי בשםCPUעם שני שדות ציבוריים:cores(u32) עבור מספר הליבות, ו-speed_ghz(f32) עבור מהירות השעון. הוסיפו מתודה בשםspecsשמחזירה String המתאר את ה-CPU בפורמט{cores}-core @ {speed_ghz}GHz.memory.rs: הגדירו מבנה ציבורי בשםMemoryעם שדה ציבורי בשםsize_gb(u32) עבור גודל הזיכרון. הוסיפו מתודה בשםspecsשמחזירה String בפורמט{size_gb}GB RAM.main.rs: כללו את שני המודולים וצרו מבנה ציבורי בשםComputerשמכיל שדהcpuמסוגCPUושדהmemoryמסוגMemory. ממשו מתודה בשםsystem_infoעבור Computer, שמעבירה את האחריות לרכיביו ומדפיסה את מפרט המערכת המלא. השתמשו בקלטים שסופקו כדי ליצור Computer ולהציג את המידע שלו.
המתודה system_info צריכה להדפיס:
System: {cpu_specs} | {memory_specs}לדוגמה, עם הקלטים 8, 3.5 ו-16:
System: 8-core @ 3.5GHz | 16GB RAMועם הקלטים 4, 2.8 ו-32:
System: 4-core @ 2.8GHz | 32GB RAMתקבלו שלושה קלטים: מספר ליבות ה-CPU (יש לנתח כ-u32), מהירות ה-CPU (יש לנתח כ-f32) וגודל הזיכרון (יש לנתח כ-u32).
נסו בעצמכם
mod cpu;
mod memory;
use cpu::CPU;
use memory::Memory;
// TODO: הגדירו struct ציבורי בשם Computer עם שני שדות ציבוריים:
// - cpu: CPU
// - memory: Memory
// TODO: ממשו מתודה system_info ב-Computer אשר:
// - מאצילה ל-cpu.specs() ול-memory.specs()
// - מדפיסה: System: {cpu_specs} | {memory_specs}
fn main() {
let mut input = String::new();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let cores: u32 = input.trim().parse().expect("Invalid number");
input.clear();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let speed_ghz: f32 = input.trim().parse().expect("Invalid number");
input.clear();
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let size_gb: u32 = input.trim().parse().expect("Invalid number");
// TODO: צרו מופעים של CPU ושל Memory באמצעות הקלטים שפוענחו
// TODO: צרו מופע של Computer עם ה-CPU וה-Memory
// TODO: קראו ל-system_info() על המחשב כדי להדפיס את התוצאה
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מתודות והתנהגות
מבוא לבלוקי מימושהפרמטר selfמתודות ניתנות לשינויפונקציות משויכותבלוקי מימוש מרוביםשרשור מתודותסיכום – פעולות מלבן4פרויקט: חיית מחמד וירטואלית
הגדרת חיית המחמדהאכלת חיית המחמדתרגלו בעצמכם: קומפיילר Rust אונליין