Hello guys!
I'm new to Rust, but read many articles and the entire book, even so I'm stuck with a problem and I'm willing to get help on how to solve this. Here is the code to reproduce the problem:
use std::fmt::Debug;
use std::rc::Rc;
use std::cell::RefCell;
use std::cell::Ref;
trait Behaviour {
fn name(&self) -> &'static str;
fn doBehaviour(&self);
}
struct SomeBehaviour;
impl Behaviour for SomeBehaviour {
fn name(&self) -> &'static str {
"Some Behaviour"
}
fn doBehaviour(&self) {
println!("Doing something...");
}
}
struct Container<'a> {
behaviours: Vec<Rc<RefCell<Behaviour + 'a>>>,
}
impl<'a> Container<'a> {
fn new<T>(main_behaviour: T) -> Container<'a>
where
T: Behaviour + 'a,
{
Container { behaviours: vec![Rc::new(RefCell::new(main_behaviour))] }
}
fn add<T>(&mut self, behaviour: T)
where
T: Behaviour + 'a,
{
self.behaviours.push(Rc::new(RefCell::new(behaviour)));
}
fn get<T>(&mut self, name: &str) -> Option<&mut T> {
if let Some(b) = self.behaviours.iter().find(|b| *b.borrow().name() == *name) {
return Some(&mut *b.borrow());
}
None
}
}
fn main() {
let mut container = Container::new(SomeBehaviour);
let someBehaviour = container.get::<SomeBehaviour>("Some Behaviour").unwrap();
println!("Got behaviour: {}", someBehaviour.name());
}
I want to have a container object which holds all behaviour objects inside it. Those object behaviours implements a trait, which I use as a generic type on behaviours vector inside container struct.
I keep the ownership with the container and give to requesters only a mutable reference, so the behaviour objects will live as long the container exists.
The problem is I don't know how to convert back from trait to generic T to return the function (get). If you attempt to run the bellow code you'll see an error saying missmatch types (T and Behaviour trait)
error[E0308]: mismatched types
--> <anon>:44:25
|
44 | return Some(&mut *b.borrow());
| ^^^^^^^^^^^^^^^^ expected type parameter, found trait Behaviour
|
= note: expected type `&mut T`
found type `&mut Behaviour + 'a`
How can I accomplish this design? On C++ I could use some reinterpret_cast and it would work.
Thanks for your attention!