简体   繁体   中英

Downcasting a Rc<RefCell<Box<struct>>> to Rc<RefCell<Box<dyn trait>>>

I have the following struct. It is just a wrapper for a vector of a given data type T :

#[derive(Debug)]
pub struct Port<T: 'static + Copy + Debug> {
    pub name: String,
    values: Vec<T>,
}

This structure implements the trait PortTrait . On the other hand, I have the following structure

#[derive(Debug)]
pub struct Component {
    pub name: String,
    ports: HashMap<String, Rc<RefCell<Box<dyn PortTrait>>>>,
}

Components share ports to communicate. I want to use a method to i) create a new port Port<T> , ii) add this new port to the component, and iii) return a pointer to the newly created port. So far, I got this:

impl Component {
    fn add_in_port<T: 'static + Copy + Debug>(&mut self, port_name: &str) -> RcCell<Box<Port<T>>> {
        let port = RcCell::new(Box::new(Port::<T>::new(port_name)));
        let x: RcCell<Box<dyn PortTrait>> = RcCell::clone(&port); // this fails
        self.ports.insert(port_name.to_string(), x);
        port
    }
}

This fails in compilation time when trying to downcast the clone of the port to a dyn PortInterface .

Do you know any way to do this?

You need to get rid of the Box .

The problem is that we allocated Rc<RefCell<Box<Port<T>>>> . Box<Port<T>> has a size of 1 usize , but now you want to convert it to Box<dyn PortTrait> which has size of 2 usize s - but there is no place in the Rc to store it!

Luckily, you don't need Box : Rc<RefCell<dyn Trait>> works just fine.

#[derive(Debug)]
pub struct Component {
    pub name: String,
    ports: HashMap<String, Rc<RefCell<dyn PortTrait>>>,
}

impl Component {
    fn add_in_port<T: 'static + Copy + Debug>(&mut self, port_name: &str) -> Rc<RefCell<Port<T>>> {
        let port = Rc::new(RefCell::new(Port::<T>::new(port_name)));
        let x = Rc::clone(&port) as Rc<RefCell<dyn PortTrait>>;
        self.ports.insert(port_name.to_string(), x);
        port
    }
}

Playground .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM