2.1 - תכונות גנריות וטיפוסים קשורים - פתרון
פתרון שני מקורות לאותו אלגוריתם¶
המקור המושאל מחזיק רק הפניה ואינדקס. הערכים המספריים מועתקים אחד בכל פעם, ואילו הבעלות בפרוסה נשארת אצל הקורא.
הוסיפו לקובץ שמגדיר את Source ואת Counter מההרצאה:
struct SliceSource<'a> {
values: &'a [u32],
index: usize,
}
impl Source for SliceSource<'_> {
type Item = u32;
fn next(&mut self) -> Option<u32> {
let value = *self.values.get(self.index)?;
self.index += 1;
Some(value)
}
}
fn statistics<S: Source<Item = u32>>(source: &mut S) -> (usize, u64) {
let mut count = 0;
let mut total = 0;
while let Some(value) = source.next() {
count += 1;
total += u64::from(value);
}
(count, total)
}
החליפו את main לצורך הבדיקה:
fn main() {
let mut counter = Counter { current: 0, end: 4 };
let values = [3, 5, 7];
let mut slice = SliceSource { values: &values, index: 0 };
assert_eq!(statistics(&mut counter), (4, 6));
assert_eq!(statistics(&mut slice), (3, 15));
assert_eq!(counter.next(), None);
assert_eq!(slice.next(), None);
}
בחרנו חוזה של סוף יציב: לאחר None המקור ימשיך להחזיר None. זהו חוזה של Source הלימודית שלנו, ולא הנחה אוטומטית על כל iterator אפשרי בראסט. האלגוריתם אינו משכפל את המקור ולכן אינו צריך Clone. החסם על Item קובע שההמרה ל־u64 והחיבור אכן מתאימים לערכי המקור.