How can I downcast from Box to a trait object type?

前端 未结 2 1210
失恋的感觉
失恋的感觉 2020-11-28 16:10
pub struct WidgetWrap {
    // ...
    widget: RefCell>,
}

At some point I want to cast Box to B

2条回答
  •  失恋的感觉
    2020-11-28 16:33

    The original code works as-is in at least Rust 1.25; presumably there was a bug or limitation in the compiler that has since been fixed:

    use std::{any::Any, cell::RefCell};
    
    trait WidgetTrait {}
    
    fn example(widget: RefCell>) {
        let mut cell = widget.borrow_mut();
        let _w = cell.downcast_mut::>();
    }
    

    As pointed out by trentcl, that doesn't mean that this does what you want:

    This compiles, I admit, but it cannot succeed when the content of the box is an object that implements WidgetTrait, because it downcasts specifically to Box. You'd have to create a Box> for it to work. (Put another way, the type parameter of downcast_mut is the unboxed type T, not Box.)

    use std::{any::Any, cell::RefCell};
    
    trait WidgetTrait {
        fn demo(&mut self);
    }
    
    fn example(widget: RefCell>) {
        let mut cell = widget.borrow_mut();
        match cell.downcast_mut::>() {
            Some(w) => w.demo(),
            None => println!("Not here!"),
        }
    }
    
    struct Alpha(u8);
    impl WidgetTrait for Alpha {
        fn demo(&mut self) {
            self.0 += 1;
            dbg!(self.0);
        }
    }
    
    fn main() {
        let b: Box = Box::new(Alpha(0));
        let r = RefCell::new(b);
        example(r);
    }
    
    Not here!
    

    Boxing it twice:

    fn main() {
        let b: Box = Box::new(Alpha(0));
        let b2: Box = Box::new(b);
        let r = RefCell::new(b2);
        example(r);
    }
    
    [src/main.rs:19] self.0 = 1
    

    See also:

    • How to get a reference to a concrete type from a trait object?

提交回复
热议问题