zsl*_*ton 6 struct event-handling rust mio
许多库允许您定义实现给定的类型trait
以用作回调处理程序.这要求您将在单个数据类型中一起处理事件所需的所有数据混为一谈,这使得借用变得复杂.
例如,mio
允许您Handler
在运行EventLoop
时实现并提供结构.考虑这些简单数据类型的示例:
struct A {
pub b: Option<B>
};
struct B;
struct MyHandlerType {
pub map: BTreeMap<Token, A>,
pub pool: Pool<B>
}
Run Code Online (Sandbox Code Playgroud)
您的处理程序具有从Token
到类型项的映射A
.每个类型的项目A
可能已经或可能没有相关的类型值B
.在处理程序中,您希望查找A
给定的值Token
,如果它还没有B
值,则从处理程序中获取一个值Pool<B>
.
impl Handler for MyHandlerType {
fn ready(&mut self, event_loop: &mut EventLoop<MyHandlerType>,
token: Token, events: EventSet) {
let a : &mut A = self.map.get_mut(token).unwrap();
let b : B = a.b.take().or_else(|| self.pool.new()).unwrap();
// Continue working with `a` and `b`
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
在这种安排中,即使直觉上可以看到self.map
并且self.pool
是不同的实体,借用检查器self
也会self.map
在我们访问时抱怨已经借用(通过)self.pool
.
一种可能的方法是将每个字段包装在MyHandlerType
中Option<>
.然后,在方法调用开始时,take()
那些值self
在调用结束时退出并恢复它们:
struct MyHandlerType {
// Wrap these fields in `Option`
pub map: Option<BTreeMap<Token, A>>,
pub pool: Option<Pool<B>>
}
// ...
fn ready(&mut self, event_loop: &mut EventLoop<MyHandlerType>,
token: Token, events: EventSet) {
// Move these values out of `self`
let map = self.map.take().unwrap();
let pool = self.pool.take().unwrap();
let a : &mut A = self.map.get_mut(token).unwrap();
let b : B = a.b.take().or_else(|| self.pool.new()).unwrap();
// Continue working with `a` and `b`
// ...
// Restore these values to `self`
self.map = Some(map);
self.pool = Some(pool);
}
Run Code Online (Sandbox Code Playgroud)
这有效,但感觉有点kluge-y.它还引入了self
为每个方法调用移入和移出值的开销.
最好的方法是什么?
Wil*_*her 14
要同时获取结构的不同部分的可变引用,请使用destructuring.这里的例子.
struct Pair {
x: Vec<u32>,
y: Vec<u32>,
}
impl Pair {
fn test(&mut self) -> usize {
let Pair{ ref mut x, ref mut y } = *self;
// Both references coexist now
return x.len() + y.len();
}
}
fn main() {
let mut nums = Pair {
x: vec![1, 2, 3],
y: vec![4, 5, 6, 7],
};
println!("{}", nums.test());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
199 次 |
最近记录: |