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