If you want to skip the cloning, you could use the AsRef
trait (playground).
impl AsRef<Age> for Age {
fn as_ref(&self) -> &Age {
self
}
}
fn sum_ages_2<A: AsRef<Age>>(ages: &[A]) -> u32 {
ages.iter().fold(0, |acc, e| acc + e.as_ref().age)
}
fn process_ages(ages: &[Option<Age>]) -> u32 {
let somes: Vec<&Age> = ages.iter()
.filter(|x| x.is_some())
.map(|x| x.as_ref().unwrap())
.collect();
sum_ages_2(&somes)
}
fn main() {
let ages: Vec<Option<Age>> = vec![Some(Age { age: 1 }), None, Some(Age { age: 2 })];
assert_eq!(process_ages(&ages), 3);
let moar_ages = vec![Age { age: 1 }, Age { age: 2 }];
assert_eq!(sum_ages_2(&moar_ages), 3);
}
This works because you are effectively "abstracting" over whether you have something or a reference to it. In this case, as long as you can get a reference to the thing then that's all we care about.