Menu
Coddy logo textTech

סעיף 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 פשוט.

challenge icon

אתגר

קל

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

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

  • processor.rs: הגדר שני traits ציבוריים ופונקציה גנרית שמשתמשת בשניהם:
    • Summarize: trait עם מתודה בשם summary שמקבלת &self ומחזירה String
    • Validate: 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.
    השתמש בקלטים שסופקו כדי ליצור Article ו-Form, ואז קרא ל-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
}
quiz iconבחנו את עצמכם

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

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

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