So I know I'm asking for something impossible here, I really need an alternative to this approach.
I have a struct containing a Vec<Box<dyn Interface>> where each Interface is reading data from some source.
Some, but not all Interfaces also impl Clock where Clock provides a timestamp used to sync the other interfaces (this is vaguely similar to GStreamer's clock system.)
I want to be able to automatically find the first struct in my vec that implements Clock and store it separately so that I can request the timestamp directly from it.
One approach I don't like is having a provides_clock method inside Interface.
#Finding a struct implementing a Trait
8 messages · Page 1 of 1 (latest)
I think
fn func<'a>(v: &'a Vec<Box<dyn Any>>) -> Option<&'a Box<dyn Clock>> {
v.iter().filter_map(|x| x.downcast_ref()).next()
}
``` would do this, but the problem is you'd need to cast a `Box<dyn Clock>` up to `Box<dyn Any>`, which I'm not sure is possible
From the docs
Note that &dyn Any is limited to testing whether a value is of a specified concrete type, and cannot be used to test whether a type implements a trait.
?play
use std::any::Any;
struct T;
struct T2;
trait Clock {}
trait Interface {}
impl Interface for T {}
impl Clock for T {}
impl Interface for T2 {}
fn func<'a>(v: &dyn Any) -> Option<&Box<dyn Clock>> {
v.downcast_ref()
}
fn main() {
let v = Box::new(T) as Box<dyn Clock>;
let v2 = Box::new(T2) as Box<dyn Interface>;
println!("{}", func(&v as &dyn Any).is_some()); // is a Box<dyn Clock>
println!("{}", func(&v2 as &dyn Any).is_some()); // isn't a Box<dyn Clock>
}
true
false
You can downcast to a boxed trait object if the original value was a boxed trait object
?play
use std::any::Any;
struct Foo;
struct Bar;
trait Clock {}
trait Interface {}
impl Interface for Foo {}
impl Interface for Bar {}
impl Clock for Bar {}
fn main() {
let interfaces: Vec<Box<dyn Interface>> = vec![
Box::new(Foo),
Box::new(Bar),
];
for interface in &interfaces {
let interface = interface as &dyn Any;
println!("{}", interface.is::<dyn Clock>());
}
}
error[E0277]: the size for values of type `dyn Clock` cannot be known at compilation time
--> src/main.rs:18:30
|
18 | println!("{}", interface.is::<dyn Clock>());
| ^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Clock`
note: required by a bound in `<(dyn Any + 'static)>::is`
For more information about this error, try `rustc --explain E0277`.