I have a function that takes a sequence of trait objects and iterates through it multiple times, e.g.,
trait Animal {
fn make_noise(&self);
}
fn make_lots_of_noises(animals: &[&dyn Animal]) {
animals.iter().for_each(|animal| animal.make_noise());
animals.iter().for_each(|animal| animal.make_noise());
animals.iter().for_each(|animal| animal.make_noise());
}
But I want the function to be able to operate on both borrowed and owned data structures. Here are the options I tried:
&[&dyn Animal]
as shown in the code fragment. Problem: if I have owned trait objects, e.g., animals: &[Box<dyn Animal>]
, then I have to call make_lots_of_noises(animals.map(Box::as_ref).collect::<Vec<_>>().as_slice()
, which involves unnecessary allocation on the heap.
&[&R] where R: AsRef<dyn Animal> + ?Sized
. Problem: T
doesn't implement AsRef<T>
! It now works with all kinds of smart pointers, but not &[&dyn Animal]
.