封闭内容器对象的生命周期推断

时间:2017-11-05 10:03:50

标签: rust closures lifetime inference

我有一个例程,它使用容器中的对象并引用存储在另外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(());
    });

}

以下是完整的游乐场链接:https://play.rust-lang.org/?gist=6079ade83e3fcf06f35397eac2e82d05&version=nightly

1 个答案:

答案 0 :(得分:2)

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

  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]。这是必需的,因为您使用的Cell结构requires a Copy type。 Derive在这里工作,因为所有struct的字段已经实现了Copy类型。

  4. Here's the updated playground