Search code examples
rustlifetime

In Rust, possible to downcast a trait to an owned type?


In Rust, I'm able to downcast a trait object to a concrete type using .as_any().downcast_ref(). That works ok, but it returns a &ref, not the owned object itself.

How can I get ownership of a downcast object?

Update: In response to the comments, here is what I was trying to do:

trait Foo {
    fn hello() -> String;
    fn as_any(&self) -> &dyn Any;
}

struct Bar {}

impl Foo for Bar {
    fn hello() -> String {
        "hello".to_owned()
    }

    fn as_any(&self) -> &dyn Any {
        self
    }
}

fn some_func(foo: impl Foo) {
    // I want a Bar here, not a &Bar
    let bar_opt = foo.as_any().downcast_ref::<Bar>();
}

I can see why .as_any() would not work, because it returns a reference.


Solution

  • This is achieved using Box and the downcast() method, which consumes the boxed trait object and returns a 'Result' containing either the downcasted object or an error if the types don't match. I would need your specific code to provide an implementation for your situation, but here's an example of its use:

    use std::any::Any;
    
    let animal: Box<dyn Any> = Box::new("Dog");
    if let Ok(dog) = animal.downcast::<String>() {
        println!("It's a dog named {}", dog);
    } else {
        println!("Not a dog");
    }
    

    The code tries to downcast a trait object 'animal' to a String, allowing us to use String methods if successful