אילוצים מרובים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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) {
// אפשר להדפיס, לסכם וגם לשכפל
}
התבנית הזאת חיונית כשהפונקציה שלך מסתמכת על כמה התנהגויות. במקום לקבל כל סוג ולקוות שהוא יעבוד, את/ה מצהיר/ה במפורש בדיוק אילו יכולות נדרשות, והמהדר אוכף זאת בזמן הקומפילציה.
אתגר
קלבואו נבנה מערכת לבדיקת מוצרים שדורשת מפריטים להיות בעלי כמה יכולות! תיצרו פונקציה גנרית שמקבלת רק טיפוסים שמממשים גם 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 שלכם
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מתודות והתנהגות
מבוא לבלוקי מימושהפרמטר selfמתודות ניתנות לשינויפונקציות משויכותבלוקי מימוש מרוביםשרשור מתודותסיכום – פעולות מלבן4פרויקט: חיית מחמד וירטואלית
הגדרת חיית המחמדהאכלת חיית המחמד8תכונות כאילוצים
תחביר של אילוצי תכונותאילוצים מרוביםסעיף whereהחזרת טיפוסים עם תכונותסיכום - מדפיס גנריתרגלו בעצמכם: קומפיילר Rust אונליין