【问题标题】:Lifetime inference for container objects inside closures闭包内容器对象的生命周期推断
【发布时间】:2017-11-05 10:03:50
【问题描述】:

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

【问题讨论】:

    标签: rust closures lifetime inference


    【解决方案1】:

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

    1. 更改handle_hand的签名

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

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

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

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

    Here's the updated playground.

    【讨论】:

    • 谢谢,我已经尝试过了,但是当我这样做时,它会阻止我将 CardCell 引用存储到 p1 或 p2 中,请考虑一下:play.rust-lang.org/…
    • 啊哈,我不认为_card 的引用可以存储在p1p2 中,因为card 的生命周期比p1/@ 短987654345@,因为它是在闭包中创建的。换句话说,你可能需要在闭包之外创建card;使其具有与p1/p2 相同的生命周期。
    • hmm,所以我可能需要更改代码的工作方式,我无法在外部创建卡,因为我需要闭包的参数来创建卡,然后将其存储在容器中,然后,实际上,可能会对其进行一些更改,然后将其存储在 p1 或 p2 中。
    • 我确实这么认为。我更改了handle_card 签名,使其在当前设置下工作:在闭包内创建卡片。但是,如果您确实打算退回到p1/p2,则必须以另一种方式创建卡片,以确保其引用寿命与p1/p2 一样长。
    猜你喜欢
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 2019-06-12
    • 2020-06-30
    • 2014-02-25
    • 1970-01-01
    • 2021-03-23
    相关资源
    最近更新 更多