לדלג לתוכן

2.7 - פונקציות סגורות ואיטרטורים - פתרון

פתרון השאלה ושכפול בשרשרת

הגרסה הראשונה אוספת מבטים, והשנייה קוראת ל־cloned אחרי הסינון כדי לשכפל רק את הנתונים שנבחרו.

fn borrowed(values: &[String]) -> Vec<&str> {
    values.iter().filter(|value| value.len() >= 4)
        .map(String::as_str).collect()
}

fn owned(values: &[String]) -> Vec<String> {
    values.iter().filter(|value| value.len() >= 4).cloned().collect()
}

fn main() {
    let values = vec!["a".into(), "long".into(), "b".into(), "other".into()];
    assert_eq!(borrowed(&values), ["long", "other"]);
    assert_eq!(owned(&values), ["long", "other"]);
    let selected: Vec<_> = values.iter()
        .inspect(|value| println!("checking {value}"))
        .filter(|value| value.len() >= 4).take(2).collect();
    assert_eq!(selected.len(), 2);

    let text = String::from("hello");
    let show = move || println!("{text}");
    show();
    show();
    let value = String::from("consumed");
    let take = move || value;
    assert_eq!(take(), "consumed");
}

המסנן עשוי לדחות איברים לפני שמתקבלות שתי תוצאות, ולכן inspect יכול לרוץ יותר מפעמיים. ה־closure show מחזיקה בעלות אבל רק קוראת ממנה, ואילו take מעבירה את המחרוזת החוצה ולכן צורכת את סביבתה.