Я сражаюсь с последним боссом ржавчины, проверкой займа. Это упрощенная версия приложения с реактивной сетью mio
, над которым я работаю. Я потратил слишком много времени на поиск правильной структуры данных для задачи. Я хочу зарегистрировать соединение во время итерации через сокеты прослушивания, которые могут принимать новые соединения.Как найти структуру без наложения изображений
См. Следующий код или на нем Rust playground. HashMap::get_mut
возвращает уникальный заем до 1 значения в 1 поле self
, поэтому я не могу перейти на self
в Thing::act
. Я понимаю, почему это происходит, как это вызывает проблему во время выполнения, но не имеет понятия, как реорганизовать структуру данных, чтобы избежать таких проблем.
use std::collections::HashMap;
trait ThingSet {
fn register(&mut self, thing: Box<Thing>);
}
trait Thing {
fn act(&mut self, reg: &mut ThingSet);
}
struct Stream;
impl Thing for Stream {
fn act(&mut self, reg: &mut ThingSet) {}
}
struct Listener;
impl Thing for Listener {
fn act(&mut self, reg: &mut ThingSet) {
if true {
let mut stream = Stream {};
reg.register(Box::new(stream));
}
}
}
struct Loop {
next: usize,
things: HashMap<usize, Box<Thing>>,
}
impl Loop {
fn new() -> Loop {
Loop { next: 1, things: HashMap::new(), }
}
fn run(&mut self) {
let mut needs_action = Vec::<&mut Box<Thing>>::new();
{
// modeling a connection on one of the listeners...
if let Some(t) = self.things.get_mut(&1usize) {
needs_action.push(t);
}
}
for t in needs_action {
t.act(self as &mut ThingSet);
}
}
}
impl ThingSet for Loop {
fn register(&mut self, thing: Box<Thing>) {
self.things.insert(self.next, thing);
self.next += 1;
}
}
fn main() {
let mut l = Loop::new();
let mut p1 = Listener {};
let mut p2 = Listener {};
l.register(Box::new(p1));
l.register(Box::new(p2));
l.run();
}
я мог бы найти хорошие учебники, объясняющие, что заимствуют проверки делает и то, что не разрешено ею. Я не мог найти хорошие учебные пособия о том, как найти альтернативные структуры данных, где я могу избежать запрещенных ссылок.
Не могли бы вы дать рекомендации о том, как переделать эту конкретную проблему?
По какой-то причине @Jsor удален свой пост, но у него было 2 хороших гов в нем: https: // play.rust-lang.org/?gist=710aefc653b320c653f289f5e3eee972 и https://play.rust-lang.org/?gist=4fecb8d2b584252fd6b6e687db34de5a – wigy
Я отвечу ответ @ breeden перед уикэндом, если кто-то не придумает структуру данных, которая позволяет статично заимствовать проверку для этого прецедента. – wigy
Я удалил его, потому что в небезопасном решении он приводит к использованию после освобождения, если вы удалите запись в 'needs_action' из' act' другого слушателя. Кроме того, ее – LinearZoetrope