How to get actual object behind dyn Trait?

I am storing objects of MyTrait in a struct Storage.

How do I access the actual underlying types Foo and Bar. I have done some research and tried it by implementing a function downcast using Any on both structs. However, the compiler complains that

method not found in std::boxed::Box<(dyn MyTrait + 'static)>

But how do I implement this in a way that I can access the underlying struct?

Or is my entire approach unreasonable? I know that I could use enums instead of Box<dyn MyTrait>, however, I want to avoid having to refactor my entire code base if I need a new struct in addition to Foo and Bar.

use std::any::Any;

trait MyTrait: Any + 'static {}
#[derive(Clone)]
struct Foo{}
#[derive(Clone)]
struct Bar{}


impl MyTrait for Foo {}

impl Foo {
    fn downcast(self) -> Option<Self> {
        match Any::downcast_ref::<Foo>(&self) {
            Some(s) => Some(s.clone()),
            None => None,
        } 
    }
}


impl MyTrait for Bar {}

impl Bar {
    fn downcast(self) -> Option<Self> {
        match Any::downcast_ref::<Bar>(&self) {
            Some(s) => Some(s.clone()),
            None => None,
        } 
    }
}


struct Storage {
    data: Vec<Box<dyn MyTrait>>,
 }

fn main() {
    
    let s = Storage{data: vec![Box::new(Foo{}), Box::new(Bar{})]};
    let first_element = s.data[0].downcast(); // compile error
    
}

Thanks for your help!

You have to downcast the trait object: You implemented it in Bar, which is already the output.
this works: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c45151cd0778624076e3ded3e98ef09c

Thanks. Of course, this makes sense.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.