闭包内容器对象的生命周期推理

Lifetime inference for container objects inside closures

我有一个例程可以处理一个容器中的对象并引用存储在另外 2 个容器中的那些对象。
但是,我没有找到这样做的生锈方法,生命周期推理似乎禁止这样做,我不知道如何解决它

fn main() {
    let mut deck : Deck = Deck::new();
    let mut p1 : Hand = Hand::new();
    let mut p2 : Hand = Hand::new();


    do_hands(|data: &[Card]| -> Result<(),()> {
      for card in data {
        deck.insert(card.id, CardCell::new(*card));

        let card: &CardCell = deck.get_mut(&card.id).unwrap();
        handle_hand(&mut card, &mut p1, &mut p2);

      }      
      return Ok(());
    });

}

这里是完整的操场 link:https://play.rust-lang.org/?gist=6079ade83e3fcf06f35397eac2e82d05&version=nightly

我在 playground 上玩了这个例子,并设法编译了代码,并进行了以下更改:

  1. 更改handle_hand

    的签名

    初始签名是 fn handle_hand<'a>(_card: &'a mut CardCell, _p1: &mut Hand<'a>, _p2: &mut Hand<'a>),但这就是编译器错误的原因。此签名要求 handle_hand 的所有输入都具有相同的生命周期,但您的代码并非如此。在闭包内部,card 的生命周期显然比 p1p2 短。所以修改后的签名就简单的变成了:fn handle_hand<'a, 'b>(_card: &'b mut CardCell, _p1: &mut Hand<'a>, _p2: &mut Hand<'a>).

  2. 更改闭包内 card 的签名。

    由于 handle_hand 需要 &mut CardCell,您必须将 card 声明为 let mut card: &mut CardCell =...

  3. 将复制特征导出到 Card 结构中。我把它放在最后,因为这可能需要根据您进一步编写结构的方式进行更改。但在这一点上,它只是u64的包装器,你可以简单地对其进行#[derive(Clone, Copy]。这是必需的,因为您正在使用 requires a Copy typeCell 结构。 Derive 在这里工作,因为你所有的结构字段都已经实现了 Copy 类型。

Here's the updated playground.