rust mopa

#[macro_use]
extern crate mopa;

struct Bear {
    // This might be a pretty fat bear.
    fatness: u16,
}

impl Bear {
    fn eat(&mut self, person: Box<dyn Person>) {
        self.fatness = (self.fatness as i16 + person.weight()) as u16;
    }
}

trait Person: mopa::Any {
    fn panic(&self);
    fn yell(&self) { println!("Argh!"); }
    fn sleep(&self);
    fn weight(&self) -> i16;
}

mopafy!(Person);

struct Benny {
    // (Benny is not a superhero. He can’t carry more than 256kg of food at once.)
    kilograms_of_food: u8,
}

impl Person for Benny {
    fn panic(&self) { self.yell() }
    fn sleep(&self) { /* ... */ }
    fn weight(&self) -> i16 {
        // Who’s trying to find out? I’m scared!
        self.yell();
        self.kilograms_of_food as i16 + 60
    }
}

struct Chris;

impl Chris {
    // Normal people wouldn’t be brave enough to hit a bear but Chris might.
    fn hit(&self, bear: &mut Bear) {
        println!("Chris hits the bear! How brave! (Or maybe stupid?)");
        // Meh, boundary conditions, what use are they in examples?
        // Chris clearly hits quite hard. Poor bear.
        bear.fatness -= 1;
    }
}

impl Person for Chris {
    fn panic(&self) { /* ... */ }
    fn sleep(&self) { /* ... */ }
    fn weight(&self) -> i16 { -5 /* antigravity device! cool! */ }
}

fn simulate_simulation(person: Box<dyn Person>, bear: &mut Bear) {
    if person.is::<Benny>() {
        // None of the others do, but Benny knows this particular
        // bear by reputation and he’s *really* going to be worried.
        person.yell()
    }
    // If it happens to be Chris, he’ll hit the bear.
    person.downcast_ref::<Chris>().map(|chris| chris.hit(bear));
    bear.eat(person);
}

fn main() {
    let mut bear = Bear { fatness: 10 };
    simulate_simulation(Box::new(Benny { kilograms_of_food: 5 }), &mut bear);
    simulate_simulation(Box::new(Chris), &mut bear);
}

  

posted @ 2022-07-25 18:28  CrossPython  阅读(16)  评论(0编辑  收藏  举报