0

由于存在大量对象的可能性,我想有一种方法将它们添加到选择列表中,删除它们进行处理,然后将它们添加回来。全部,无需在每次将对象添加回来等待时重新构建选择列表。它看起来像这样:

use std::collections::HashMap;
use crossbeam::{Select, Sender, Receiver};

struct WaitList <'a> {
    sel: Select<'a>,
    objects: HashMap<u128, Object>,
    sel_index: HashMap<usize, u128>,
}
impl<'a> WaitList<'a> {
    fn new () -> Self { Self { sel: Select::new(), objects: HashMap::new(), sel_index: HashMap::new() } }
    fn select(&self) -> &Object {
        let oper = self.sel.select();
        let index = oper.index();
        let id = self.sel_index.get(&index).unwrap();
        let obj = self.objects.get(&id).unwrap();
        obj.cmd = oper.recv(&obj.receiver).unwrap();
        self.sel.remove(index);
        obj
    }

    fn add_object(&self, object: Object) {
        let id = object.id;
        self.objects.insert(id, object);
        self.add_select(id);
    }

    fn add_select(&self, id: u128) {
        let idx = self.sel.recv(&self.objects.get(&id).unwrap().receiver);
        self.sel_index.insert(idx, id);
    }
}

随着时间的推移,选择列表将包含更多的死条目,然后是活的,我会在那个时候重建它。但是,我不想每次都重建它。这是详细的错误消息:

    Checking test-select v0.1.0 (/Users/bruce/Projects/rust/examples/test-select)
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
  --> src/main.rs:28:47
   |
28 |         let idx = self.sel.recv(&self.objects.get(&id).unwrap().receiver);
   |                                               ^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 27:5...
  --> src/main.rs:27:5
   |
27 | /     fn add_select(&self, id: u128) {
28 | |         let idx = self.sel.recv(&self.objects.get(&id).unwrap().receiver);
29 | |         self.sel_index.insert(idx, id);
30 | |     }
   | |_____^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:28:34
   |
28 |         let idx = self.sel.recv(&self.objects.get(&id).unwrap().receiver);
   |                                  ^^^^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 9:6...
  --> src/main.rs:9:6
   |
9  | impl<'a> WaitList<'a> {
   |      ^^
note: ...so that the types are compatible
  --> src/main.rs:28:28
   |
28 |         let idx = self.sel.recv(&self.objects.get(&id).unwrap().receiver);
   |                            ^^^^
   = note: expected `&mut crossbeam::Select<'_>`
              found `&mut crossbeam::Select<'a>`

虽然我相信我理解这个问题,从哈希表中借用接收器的时间不够长,但我很难想出一个替代方案——而且我没有看到一个干净的方法借资料。我考虑创建一个结构来包含借用,并在等待 sel_index 中使用它而不是普通的 id,但这会遇到相同的生命周期问题。

struct SingleWaiter<'a> {
    id: u128,
    receiver: &'a Receiver::<Command>
}

我觉得我错过了一些东西或不理解一些东西,因为看起来做我想做的事情不应该那么难。我可以想象选择 HashMap 来保存对象可能是问题所在,因为我正在添加和插入,所以 Vec 感觉不对。顺便说一句,HashMap 通常不属于候补名单。它是其他东西的一部分,但无论 HashMap 位于何处,问题仍然存在。

4

0 回答 0