Насколько я понимаю из вашего кода, ваша главная цель - добавить всех клиентов / субъектов в коллекцию и вызывать обычное поведение, когда это необходимо. Но из-за безопасности объектов это невозможно, поэтому мы можем сделать это с небольшим взломом (создавая черту, которая имитирует Клиента, я назвал ее ClientProxy ).
У меня есть собственная черта, которая определяет интерфейс для сторонних интеграций.Давайте назовем это Клиентом.Я хочу, чтобы каждый клиент вел себя как актер.
pub trait Client: Actor {}
Да, это работает так, на самом деле это означает, что если какая-то структура имеет реализацию Client, она должна также иметь реализацию Actor.
Предположим, у нас есть два Context MyActor и OtherActor и их реализации Client / Actor.И у нас есть поведение в клиенте (поведение_like_client (& self)).
pub trait Client: Actor {
fn behave_like_a_client(&self);
}
struct MyActor {
count: usize,
}
impl Actor for MyActor {
type Context = Context<Self>;
}
impl Client for MyActor {
fn behave_like_client(&self) {
println!("I am MyActor as Client, and my count is {}", self.count);
}
}
struct OtherActor {
count: usize,
}
impl Actor for OtherActor {
type Context = Context<Self>;
}
impl Client for OtherActor {
fn behave_like_client(&self) {
println!("I am OtherActor Client, and my count is {}", self.count);
}
}
Теперь у нас есть наши актеры для тестирования, но давайте вернемся к нашей проблеме безопасности объектов, мы не можем собрать этих клиентов в одинколлекция.Вот почему я создал ClientProxy
для имитации Client
и хочу реализовать ClientProxy
на Clients
.Мы можем сделать это с помощью реализации ClientProxy
в Generics, которая расширяет возможности клиентов:
//ClientProxy must have all behaviors in Client
trait ClientProxy {
fn behave_like_client(&self);
}
//This code implements ClientProxy to all Client like Objects
impl<T> ClientProxy for T
where
T: Client,
{
fn behave_like_client(&self) {
self.behave_like_client();
}
}
Теперь все готово, мы можем проверить нашу структуру:
struct Container {
clients: Vec<Box<ClientProxy>>,
}
fn main() {
let mut container = Container {
clients: Vec::new(),
};
let a = Box::new(MyActor { count: 3 });
let b = Box::new(OtherActor { count: 4 });
container.clients.push(a);
container.clients.push(b);
container
.clients
.iter()
.for_each(|a| a.behave_like_client());
//output :
//I am MyActor as Client, and my count is 3
//I am OtherActor Client, and my count is 4
}
Вы можете получить полный кодс детская площадка (не работает на детской площадке из-за отсутствия зависимости)