Is it possible to pass traits as parameters to generic functions like this?
trait Fnord {
fn do_it(&self) -> i32 { 42 }
}
impl Fnord for i32 {}
fn iter_as<'a, T>(objs: &'a [i32]) -> impl Iterator<Item = & 'a dyn T>
{
objs.iter().map(|o| o as &dyn T)
}
fn main() {
let objs: Vec<i32> = vec![1, 2, 3];
// Calls would look like this
for s in iter_as::<Fnord>(&objs) {
println!("{}", s.do_it());
}
}
This produce me these errors:
error[E0404]: expected trait, found type parameter `T`
--> src/lib.rs:7:69
|
7 | fn iter_as<'a, T>(objs: &'a [i32]) -> impl Iterator<Item = & 'a dyn T>
| ^ not a trait
error[E0404]: expected trait, found type parameter `T`
--> src/lib.rs:9:35
|
9 | objs.iter().map(|o| o as &dyn T)
| ^ not a trait
warning: trait objects without an explicit `dyn` are deprecated
--> src/lib.rs:16:24
|
16 | for s in iter_as::<Fnord>(&objs) {
| ^^^^^ help: use `dyn`: `dyn Fnord`
|
= note: `#[warn(bare_trait_objects)]` on by default
That is, can iter_as
accept a trait as a generic parameter so that it can return an iterable of that trait? I've searched quite a bit for an answer, but at this point I feel like I may be asking the wrong question.
The background is like this. I've got a struct with several vectors of different concrete types, all of which implement the same traits. I'd like the struct's impl to have a function that can return an iterable over all of the stored objects as any of their common traits. The iter_as
above is a simplified version of that (notional) function. Perhaps I'm simply approaching this in an awkward way for rust (i.e. maybe I'm thinking too much like a C++ programmer), so an alternative, idiomatic approach would be great, too.