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
}
}
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.