【问题标题】:Passing local lifetime to satisfy trait通过本地生命周期来满足特征
【发布时间】:2019-09-04 20:57:06
【问题描述】:

我有一个通用函数创建一个本地对象并采用一个特征来指定如何处理该对象。 trait 获取对对象的引用并在其生命周期内保存它(以避免一次又一次地将它传递给每个函数调用)。它在

之前死去
fn do_stuff<'a, T>()
  where T : BigBorrower<'a>
{
  let borrowee = Borrowed{ data : 1 };
  {
    let _borrowee = T::new(&borrowee);
  }
}

这是函数调用。因为 trait 的生命周期必须在函数声明中指定,这使得编译器认为生命周期延长了 _borrowee 的生命周期。

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a445fb4ab7befefbadd3bdb8fb43c86a

   |
24 | fn do_stuff<'a, T>()
   |             -- lifetime `'a` defined here
...
29 |     let _borrowee = T::new(&borrowee);
   |                     -------^^^^^^^^^-
   |                     |      |
   |                     |      borrowed value does not live long enough
   |                     argument requires that `borrowee` is borrowed for `'a`
30 |   }
31 | }
   | - `borrowee` dropped here while still borrowed

【问题讨论】:

标签: rust lifetime


【解决方案1】:

您刚刚遇到了生命周期和编译器的问题之一。一旦你意识到它发生的原因,这就是有道理的。

您的方法调用为您提供的泛型类型强制执行生命周期'a。这意味着,除其他事项外,这一生命周期需要得到尊重,并且所有对象都必须活得那么久。实际上,当您这样做时,生命周期就是函数调用的生命周期。

通过传递 T::new() 对局部变量的引用,您将强制编译器选择低于 'a 的生命周期(因为它不会超过函数调用),因此,您将违背您的自己的要求。

通常,您解决此问题的方法是将您的 do_stuff&lt;'a, T&gt; 分成两部分,例如 this playground sample。这使得编译器可以接受生命周期检查,因为该引用的预期寿命保证比被调用函数的寿命长。

请注意,我在 trait 和 implementations 中将您的方法 new 重命名为 borrow,因为它更接近它的本质。

【讨论】:

  • 有没有办法在具有 Trait 的代理函数中创建对象?理想情况下,我想隐藏创建中间对象的事实,因为它是一个实现细节,我只想将特征传递给第一个函数。现在我更好地理解了这个问题,这不是和stackoverflow.com/questions/28029565/…一样的问题吗?基本上我不能在没有生命周期约束的情况下通过这个特征......
  • 这确实是同一个问题,也突出了一个事实,即现在不能直接完成。根本没有办法以满足现在条件的方式来表达这一寿命要求。一个问题-关于对象的创建-根对象(在您的情况下为Borrowed)是以任何方式共享还是复制?如果没有,您不妨让Borrowee 拥有它。
猜你喜欢
  • 2021-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
  • 2018-02-12
  • 2017-11-08
  • 1970-01-01
  • 2016-03-10
相关资源
最近更新 更多