Шаблон посетителей в Русте - PullRequest
0 голосов
/ 24 декабря 2018

Я нашел интересную реализацию шаблона посетителя в Rust :

pub trait Visitor<T> {
    fn visit(&mut self, t: &T);
}

pub trait Visitable: Sized {
    fn accept<T>(&self, t: &mut T)
    where
        T: Visitor<Self>,
    {
        t.visit(self);
    }
}

Поскольку Visitable не является безопасным для объекта, я не могу сохранить Vec изVisitable объектов.Я нашел решение аналогичной проблемы , можно ли было бы сделать аналогичное решение для Visitable?

1 Ответ

0 голосов
/ 24 декабря 2018

Visitable - это черта, а черты не имеют размера (разработчикам не гарантируется одинаковый размер).Вам нужно хранить то, что имеет размер.Оберните значения в Box, а затем используйте его следующим образом:

trait VisitorTrait {
    fn visit(&self, visitable: &Box<VisitableTrait>);
}

struct Visitor1 {}
struct Visitor2 {}

impl VisitorTrait for Visitor1 {
    fn visit(&self, visitable: &Box<VisitableTrait>) {
        println!("visited via Visitor1");
        visitable.accept()
    }
}

impl VisitorTrait for Visitor2 {
    fn visit(&self, visitable: &Box<VisitableTrait>) {
        println!("visited via Visitor2");
        visitable.accept()
    }
}

trait VisitableTrait {
    fn accept(&self);
}

#[derive(Clone)]
struct Visitable1 {}
#[derive(Clone)]
struct Visitable2 {}

impl VisitableTrait for Visitable1 {
    fn accept(&self) {
        println!("accepted1.");
    }
}

impl VisitableTrait for Visitable2 {
    fn accept(&self) {
        println!("accepted2.");
    }
}

fn main() {
    let visitor1 = Visitor1 {};
    let visitor2 = Visitor2 {};
    let visitable1 = Visitable1 {};
    let visitable2 = Visitable2 {};

    let mut visitors: Vec<Box<VisitorTrait>> = Vec::new();
    let mut visitables: Vec<Box<VisitableTrait>> = Vec::new();

    visitors.push(Box::new(visitor1));
    visitors.push(Box::new(visitor2));

    visitables.push(Box::new(visitable1));
    visitables.push(Box::new(visitable2));

    for visitable in visitables.iter() {
        for visitor in visitors.iter() {
            visitor.visit(visitable.clone());
        }
    }
}

Игровая площадка

Мы объявляем две разные черты для посетителя и посещаемых и прохожденияпосещаемые с помощью посетителей с двумя петлями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...