通过本地生命周期来满足特征

Passing local lifetime to satisfy 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

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

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

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

通常,解决此问题的方法是将 do_stuff<'a, T> 一分为二,就像 this playground sample 一样。这使得编译器可以接受生命周期检查,因为该引用的预期寿命保证比被调用函数的预期寿命长。

请注意,我在特性和实现中将您的方法 new 重命名为 borrow,因为这更接近于它的本来面目。