generated from rust-lang/project-group-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Closed
Labels
Description
Code description
By using Any
as a supertrait, this feature enables quite nice conversions (upcasts and downcasts) between types in a 2-level depth trait-type taxonomy:
use std::any::Any;
trait Node: Any {}
#[derive(Debug)]
struct Node1 {
data: i32,
}
impl Node for Node1 {}
#[derive(Debug)]
struct Node2 {
data: f64,
}
impl Node for Node2 {}
fn visit_all_nodes(nodes: &[Box<dyn Node>]) {
for node in nodes.iter() {
let node: &dyn Node = &**node;
if let Some(node1 @ Node1 { .. }) = (node as &dyn Any).downcast_ref::<Node1>() {
println!("{:?}", node1);
} else if let Some(node2 @ Node2 { .. }) = (node as &dyn Any).downcast_ref::<Node2>() {
println!("{:?}", node2);
} else {
println!("unknown node");
}
}
}
fn main() {
let nodes: Vec<Box<dyn Node>> =
vec![Box::new(Node1 { data: 42 }), Box::new(Node2 { data: 99.0 })];
visit_all_nodes(&nodes[..]);
}
outputs:
Node1 { data: 42 }
Node2 { data: 99.0 }
What worked well
This is much more ergonomic than asking each node to implement as_any_ref
and as_any_mut
to enable downcasting.
What worked less well
The (node as &dyn Any).downcast_ref
syntax still looks a little cumbersome.