סעיף where
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Rust של Coddy. שיעור 42 מתוך 61.
ככל שמוסיפים יותר חסמי תכונות, חתימות של פונקציות עלולות להיות קשות לקריאה. נבחן פונקציה עם כמה פרמטרים גנריים, שכל אחד מהם דורש כמה תכונות:
fn complex_operation<T: Display + Clone, U: Debug + Summary>(first: T, second: U) {
// ...
}
זה עובד, אבל החתימה נעשית עמוסה. סעיף where מציע חלופה נקייה יותר, על ידי העברת אילוצי התכונות לאחר רשימת הפרמטרים:
fn complex_operation<T, U>(first: T, second: U)
where
T: Display + Clone,
U: Debug + Summary,
{
// ...
}
שתי הגרסאות זהות מבחינה פונקציונלית: סעיף where נועד רק לשיפור הקריאות. הדרישות של כל טיפוס מופיעות בשורה משלהן, כך שקל לסרוק ולראות מה כל פרמטר גנרי צריך.
סעיף where נעשה שימושי במיוחד כשהאילוצים מורכבים או כשיש לך פרמטרים גנריים רבים. הוא משאיר את שם הפונקציה ואת הפרמטרים גלויים במבט חטוף, כשהאילוצים מופיעים בנפרד מתחתיהם. זהו הסגנון המועדף ברוב בסיסי הקוד של Rust כשהאילוצים חורגים מ־T: Trait פשוט.
אתגר
קלבואו נבנה מערכת לעיבוד נתונים שמשתמשת בסעיף where כדי לשמור על קריאות של חסמי traits מורכבים! תיצור פונקציה גנרית עם כמה פרמטרים של טיפוסים, שכל אחד מהם דורש traits שונים, ותארגן את החסמים בצורה מסודרת באמצעות תחביר where.
תארגן את הקוד שלך בשני קבצים:
processor.rs: הגדר שני traits ציבוריים ופונקציה גנרית שמשתמשת בשניהם:Summarize: trait עם מתודה בשםsummaryשמקבלת&selfומחזירהStringValidate: trait עם מתודה בשםvalidateשמקבלת&selfומחזירהbool
process_itemsשמקבלת שני פרמטרים מטיפוסים גנריים שונים. השתמש בסעיףwhereכדי לציין שהטיפוס הראשון חייב לממש גם אתCloneוגם אתSummarize, ואילו הטיפוס השני חייב לממש אתValidate. הפונקציה צריכה להדפיס את הסיכום של הפריט הראשון, ולאחר מכן להדפיס אם הפריט השני תקף.main.rs: צור שתי מבנים ציבוריים שמממשים את ה-traits הנדרשים:Article: עם שדה ציבורי בשםtitle(String). ממש אתSummarizeכך שיחזירArticle: {title}, והפק נגזרתClone.Form: עם שדה ציבורי בשםfilled(bool). ממש אתValidateכך שיחזיר את הערך שלfilled.
process_itemsעם שניהם.
סעיף where הופך את חתימת הפונקציה שלך להרבה יותר נקייה מאשר לדחוס את כל החסמים בין סוגריים זוויתיים. הדרישות של כל טיפוס מופיעות בשורה משלהן, וכך קל לראות מה כל פרמטר גנרי צריך.
הפלט שלך צריך להציג את הסיכום ולאחריו את תוצאת האימות:
Article: {title}
Valid: {true/false}לדוגמה, עם הקלטים Rust Tips ו-true:
Article: Rust Tips
Valid: trueועם הקלטים Breaking News ו-false:
Article: Breaking News
Valid: falseתקבל שני קלטים: כותרת הכתבה והאם הטופס מלא (יש לנתח כ-bool).
נסו בעצמכם
mod processor;
use processor::{Summarize, Validate, process_items};
use std::io;
// TODO: הגדירו struct ציבורי בשם Article עם שדה ציבורי בשם title מסוג (String)
// גזרו Clone עבור Article
// TODO: ממשו את Summarize עבור Article
// המתודה summary צריכה להחזיר "Article: {title}"
// TODO: הגדירו struct ציבורי בשם Form עם שדה ציבורי בשם filled מסוג (bool)
// TODO: ממשו את Validate עבור Form
// המתודה validate צריכה להחזיר את הערך של filled
fn main() {
let mut title = String::new();
io::stdin().read_line(&mut title).expect("Failed to read line");
let title = title.trim().to_string();
let mut filled_input = String::new();
io::stdin().read_line(&mut filled_input).expect("Failed to read line");
let filled: bool = filled_input.trim().parse().expect("Failed to parse bool");
// TODO: צרו Article עם ה-title הנתון
// TODO: צרו Form עם הערך הנתון של filled
// TODO: קראו ל-process_items עם ה-article וה-form
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מתודות והתנהגות
מבוא לבלוקי מימושהפרמטר selfמתודות ניתנות לשינויפונקציות משויכותבלוקי מימוש מרוביםשרשור מתודותסיכום – פעולות מלבן4פרויקט: חיית מחמד וירטואלית
הגדרת חיית המחמדהאכלת חיית המחמד8תכונות כאילוצים
תחביר של אילוצי תכונותאילוצים מרוביםסעיף whereהחזרת טיפוסים עם תכונותסיכום - מדפיס גנריתרגלו בעצמכם: קומפיילר Rust אונליין