struct - 同时改变多个结构字段的最快惯用方法是什么?

标签 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>
}

您的处理程序有来自 Token 的 map 到 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`
       // ...
    }
}

在这种排列中,尽管从直觉上可以看出 self.mapself.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);
}

这可行,但感觉有点笨拙。它还引入了将值移入和移出 self 的开销。对于每个方法调用。

执行此操作的最佳方法是什么?

最佳答案

要同时获取对结构不同部分的可变引用,请使用解构。示例 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());
}

关于struct - 同时改变多个结构字段的最快惯用方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32403895/

相关文章:

python - 从类型 'MyStruct' 到类型 'void*' 的强制转换无效

c# - 如何将事件监听器添加到通过依赖项注入(inject)实例化的对象?

javascript - 聚焦并模糊不冒泡的 jQuery 事件

javascript - jQuery.on();与 JavaScript .addEventListener();

go - gRPC客户端不占用服务器端流

error-handling - 如果没有结果,则从 for 循环返回结果或不返回结果

python - 将 struct.pack 与字符串一起使用

C++:将结构传递给 PThread

c - 在 C 中取消引用指向不完整类型(具有明确定义的结构)的指针

floating-point - 使用泛型时如何使用 float 文字?