Skip to content

Instantly share code, notes, and snippets.

@335g
Last active March 31, 2018 09:58
Show Gist options
  • Save 335g/f7b5efcaffb5fa9d58af18c3bf1041be to your computer and use it in GitHub Desktop.
Save 335g/f7b5efcaffb5fa9d58af18c3bf1041be to your computer and use it in GitHub Desktop.
type erasure (closure type) in rust
trait AnimalExt {
type Food;
fn eat(&self, food: Self::Food);
}
struct Dog;
impl AnimalExt for Dog {
type Food = String;
fn eat(&self, food: String) {
println!("Dog eats {:?}", food);
}
}
struct Cat;
impl AnimalExt for Cat {
type Food = u32;
fn eat(&self, food: u32) {
println!("Cat eats {:?}", food);
}
}
struct AnyAnimal<T> {
eat: Box<Fn(T)>,
}
impl<T> AnyAnimal<T> {
fn new<A>(animal: A) -> Self
where
A: AnimalExt<Food=T> + 'static,
{
AnyAnimal {
eat: Box::new(move |food| animal.eat(food)),
}
}
}
impl<T> AnimalExt for AnyAnimal<T> {
type Food = T;
fn eat(&self, food: T) {
(self.eat)(food)
}
}
fn main() {
let dog = AnyAnimal::new(Dog);
dog.eat("meet".to_string());
let cat = AnyAnimal::new(Cat);
cat.eat(1);
// cat.eat("Dog food"); <- compile error
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment