trait Actor{
fn actor(&self);
}
trait Health{
fn health(&self);
}
struct Plant;
impl Actor for Plant{
fn actor(&self){
println!("Plant Actor");
}
}
struct Monster{
health: f32
}
impl Actor for Monster{
fn actor(&self){
println!("Monster Actor");
}
}
impl Health for Monster{
fn health(&self){
println!("Health: {}",self.health);
}
}
fn main() {
let plant = Box::new(Plant);
let monster = Box::new(Monster{health: 100f32});
let mut actors : Vec<Box<Actor>> = Vec::new();
actors.push(plant);
actors.push(monster);
for a in &actors{
a.actor();
/* Would this be possible?
let health = a.get_trait_object::<Health>();
match health{
Some(h) => {h.health();},
None => {println!("Has no Health trait");}
}
*/
}
}
I am wondering if something like this could be possible?
let health = a.get_trait_object::<Health>();
match health{
Some(h) => {h.health();},
None => {println!("Has no Health trait");}
}
As of 1.0, no. Rust doesn't provide any dynamic downcasting support, with the exception of
Any
; however, that only allows you to downcast to a value's specific concrete type, not to arbitrary traits that said concrete type implements.I believe you could implement such casting manually, but that would require unsafe code that would be easy to get wrong; not the sort of thing I want to try and summarise in an SO answer.
It is not possible to do this in Rust at present, nor is it likely to ever become possible; it is, however, possible to construct similar abstractions as part of your trait:
Rust is expected to get negative bounds at some point; when that comes, you’ll be able to have something like this:
This will reduce the boilerplate from every implementation of a trait to just one per trait, but that stage is not yet upon us. Still, you could take the middle ground of the two approaches:
Play around with different ways of handling it until you find something you like! The possibilities are limitless! (Because Rust is Turing‐complete.)