Menu
Coddy logo textTech

אילוצים מרובים

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

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

כך מציינים שסוג חייב לממש שתי תכונות:

use std::fmt::Display;

trait Summary {
    fn summarize(&self) -> String;
}

fn announce<T: Display + Summary>(item: T) {
    println!("Breaking news: {}", item);
    println!("Summary: {}", item.summarize());
}

האילוץ T: Display + Summary פירושו "‏T חייב לממש גם את Display וגם את Summary." בתוך הפונקציה, אפשר להשתמש ביכולות של שתי התכונות: הדפסה באמצעות {} (מתוך Display) וקריאה ל־summarize() (מתוך Summary).

אפשר לשרשר כמה תכונות שצריך:

fn process<T: Display + Summary + Clone>(item: T) {
    // אפשר להדפיס, לסכם וגם לשכפל
}

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

challenge icon

אתגר

קל

בואו נבנה מערכת לבדיקת מוצרים שדורשת מפריטים להיות בעלי כמה יכולות! תיצרו פונקציה גנרית שמקבלת רק טיפוסים שמממשים גם trait מותאם אישית וגם trait סטנדרטי, ותדגימו כיצד התחביר + משלב כמה חסמים.

תארגנו את הקוד בשני קבצים:

  • product.rs: הגדירו trait ציבורי בשם Inspectable עם מתודה בשם inspect שמקבלת את &self ומחזירה String שמכיל פרטי בדיקה. לאחר מכן, צרו struct ציבורי בשם Gadget עם שדות ציבוריים name מסוג (String) ו-serial מסוג (u32). על Gadget לממש גם את Inspectable (ולהחזיר Inspecting: {name}) וגם את std::fmt::Display (ולעצב בתבנית {name} (SN: {serial})). לבסוף, צרו פונקציה גנרית ציבורית בשם full_report שמקבלת כל טיפוס T שמממש גם את Display וגם את Inspectable. הפונקציה צריכה להדפיס שתי שורות: תחילה את הפריט באמצעות המתאם {}, ולאחר מכן את התוצאה של קריאה ל-inspect().
  • main.rs: כללו את מודול המוצרים שלכם וצרו מופע של Gadget באמצעות הקלטים שסופקו. קראו ל-full_report עם הגאדג'ט שלכם כדי להראות שהוא עומד בדרישות של שני ה-trait.

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

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

{name} (SN: {serial})
Inspecting: {name}

לדוגמה, עבור הקלטים Smartwatch ו-98765:

Smartwatch (SN: 98765)
Inspecting: Smartwatch

תקבלו שני קלטים: שם הגאדג'ט והמספר הסידורי (יש לנתח כ-u32).

נסו בעצמכם

mod product;

use product::{Gadget, full_report};

fn main() {
    // קראו את הקלטים
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Failed to read line");
    let name = name.trim().to_string();
    
    let mut serial_input = String::new();
    std::io::stdin().read_line(&mut serial_input).expect("Failed to read line");
    let serial: u32 = serial_input.trim().parse().expect("Failed to parse serial");
    
    // TODO: צרו מופע של Gadget עם השם והמספר הסידורי
    
    // TODO: קראו ל-full_report עם ה-Gadget שלכם
}
quiz iconבחנו את עצמכם

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

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

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