Last active
March 31, 2018 09:58
-
-
Save 335g/f7b5efcaffb5fa9d58af18c3bf1041be to your computer and use it in GitHub Desktop.
type erasure (closure type) in rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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