什么是同时改变多个结构域的最快惯用方法?

时间:2015-09-04 17:50:58

标签: struct event-handling rust mio

许多库允许您定义实现给定trait的类型以用作回调处理程序。这要求您将在单个数据类型中处理事件所需的所有数据混为一谈,这会使借用变得复杂。

例如,mio允许您实施Handler并在run the EventLoop时提供您的结构。考虑一下这些简单数据类型的示例:

struct A {
  pub b: Option<B>
};

struct B;

struct MyHandlerType {
  pub map: BTreeMap<Token, A>,
  pub pool: Pool<B>
}

您的处理程序包含从TokenA类型的项目的地图。类型A的每个项目可能已经或可能没有类型B的关联值。在处理程序中,您希望查找给定A的{​​{1}}值,如果它还没有Token值,请从处理程序{{1}中获取一个值}}

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` // ... } } 是不同的实体,借阅检查器也会抱怨self.map已经借用了(self.pool )当我们去访问self时。

一种可能的方法是将self.map中的每个字段打包在self.pool中。然后,在方法调用开始时,MyHandlerType Option<>之外的值,并在通话结束时恢复它们:

take()

这可行,但感觉有点kluge-y。它还引入了为每个方法调用移入和移出self值的开销。

最好的方法是什么?

1 个答案:

答案 0 :(得分:13)

要同时获取结构的不同部分的可变引用,请使用destructuring。示例here

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());
}