Skip to content

Instantly share code, notes, and snippets.

@henninglive
Created March 22, 2018 03:40
Show Gist options
  • Select an option

  • Save henninglive/deca8154538b4f80a433cb418604f8f5 to your computer and use it in GitHub Desktop.

Select an option

Save henninglive/deca8154538b4f80a433cb418604f8f5 to your computer and use it in GitHub Desktop.
Example showing how to fold a list with different types using dynamic dispatch.
#[macro_use]
extern crate mopa;
use std::any::TypeId;
use std::fmt::Debug;
// Add std::any::Any methods to Object.
mopafy!(Object);
trait Object: mopa::Any + Debug {
/// Useful as key in maps, for axample HashMap<TypeId, Box<Object>>
fn type_id(&self) -> TypeId {
TypeId::of::<Self>()
}
fn add(&self, other: &Object) -> Box<Object>;
}
impl Object for isize {
fn add(&self, other: &Object) -> Box<Object> {
if other.is::<isize>() {
let o = other.downcast_ref::<isize>().unwrap();
return Box::new(*self + *o);
}
if other.is::<f64>() {
let o = other.downcast_ref::<f64>().unwrap();
return Box::new(*self as f64 + *o);
}
panic!("Unknown type")
}
}
impl Object for f64 {
fn add(&self, other: &Object) -> Box<Object> {
if other.is::<f64>() {
let o = other.downcast_ref::<f64>().unwrap();
return Box::new(*self as f64 + *o);
}
if other.is::<isize>() {
let o = other.downcast_ref::<isize>().unwrap();
return Box::new(*self + *o as f64);
}
panic!("Unknown type");
}
}
fn main() {
let l: Vec<Box<Object>> = vec![
Box::new(1isize), Box::new(2isize),
Box::new(3.0f64), Box::new(4.0f64)
];
let sum = l.iter().fold::<Box<Object>, _>(Box::new(0isize), |acc, i| acc.add(&**i));
println!("Sum: {:?}", sum);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment