rust 类型生存期绑定的用途是什么?

0tdrvxhp  于 2023-10-20  发布在  其他
关注(0)|答案(3)|浏览(91)
fn foo<'a, T>()
where T : 'a 
{
   //code a
}

fn foo()
{
   //code b
}

其中类型T是具有生存期参数的任何类型。代码a中可以做的而代码b中不能做的事情是什么?
我希望它们是完全相同的,因为我不明白其中的区别,也不知道生命周期的界限是什么。如果第一个函数能使解释用例更容易(比如参数),你可以建议对第一个函数进行添加。

xfb7svmp

xfb7svmp1#

在下面的代码中,你可以看到绑定是必需的:

trait Elem {}

struct List<'a> {
    v: Vec<Box<dyn Elem + 'a>>,
}

impl<'a> List<'a> {
    fn push<T: Elem>(&mut self, t: T) {
        self.v.push(Box::new(t));
    }
}
error[E0309]: the parameter type `T` may not live long enough
 --> src/lib.rs:9:21
  |
9 |         self.v.push(Box::new(t));
  |                     ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
  |
help: consider adding an explicit lifetime bound...
  |
8 |     fn push<T: Elem + 'a>(&mut self, t: T) {
  |                     ++++

从本质上讲,泛型类型可以有任何生存期,但有时需要在只允许特定生存期的上下文中使用泛型类型。在这种情况下,List<'a>只能保存至少与'a一样长的元素。因此,T: 'a约束存在于这些情况下。T: 'static是这种语法最常见的情况,它表示类型可能根本不包含任何本地引用。

cetgtptt

cetgtptt2#

通常,当类型想要保存对它不拥有的数据的引用时,将使用它。
我认为Cow可能是一个很好的例子。
如链接所示,其完整签名为:

pub enum Cow<'a, B>
where
    B: 'a + ToOwned + ?Sized,
{
    Borrowed(&'a B),
    Owned(<B as ToOwned>::Owned),
}

lifetime参数允许结构体包含对B的引用,但不拥有它。由于Cow不是B的所有者,因此借用检查器需要知道B将存活多久,以防止引用Cow保持悬空。

jtw3ybtb

jtw3ybtb3#

其他问题给出了需要明确界限的例子,但没有完全概括地回答这个问题。
fn foo1<'a, T: 'a>() {...}fn foo2<T>() {...}之间的区别在于,在foo1中,您可以命名'a。在foo2中,您不能表达与T相关的 * 显式 * 生存期界限。受此约束限制的确切操作可能会随着时间的推移而改变,因为Rust可能会改变其他约束隐含的生命周期界限。
例如,当你在代码中的某个地方提到&'a T时,你隐含地暗示了T: 'a。过去情况并非如此。

相关问题