【问题标题】:What does it mean when a generic type is bounded by a generic lifetime?当泛型类型受泛型生命周期限制时,这意味着什么?
【发布时间】:2020-05-19 06:48:56
【问题描述】:

我正在研究 Rust 的生命周期。生命周期用'a 表示,可以这样使用:

fn function1<'a>(param1: &'a str) -> &'a str

但是我发现了这段代码:

impl<'a, T: 'a> RingBuffer<'a, T> {

T 的类型为 'a 对我来说毫无意义。类型和生命周期对我来说不是一回事。发生了什么事?

【问题讨论】:

    标签: generics rust lifetime borrow-checker borrowing


    【解决方案1】:

    T: 'aT 的生命周期。来自rust reference

    T: 'a 表示T 的所有生命周期参数都超过了'a。例如 如果'a 是一个不受约束的生命周期参数,那么i32: 'static&amp;'static str: 'a 满意,但 Vec&lt;&amp;'a ()&gt;: 'static 不满意。

    在您给出的特定代码段中,生命周期绑定 T: 'a 是说您放入环形缓冲区的东西的生命周期必须至少与 RingBuffer 的生命周期一样长。

    【讨论】:

    • Vec&lt;&amp;'a ()&gt;: 'static 不能放入引用 let x: &amp;'static Vec&lt;something&gt; 因为 Vec&lt;&amp;'a ()&gt; 的内部生命周期小于 static?能给我举个例子吗?我不知道该放什么something
    【解决方案2】:

    当你看到一个泛型类型参数后跟一个冒号和一个生命周期时,这意味着一个生命周期边界被放置在该类型上。

    例如,在您引用的情况下:

    impl<'a, T: 'a> RingBuffer<'a, T> {
    

    T 类型的生命周期必须至少与 'a 的生命周期一样长(请注意,编译器不知道 T 是什么 - T 本身可能包含引用或包含其他包含引用的类型)。

    更仔细地查看implementation of RingBuffer(我假设您在 smoltcp crate 中找到了它),您可以看到原因:RingBuffer 可能包含对借用缓冲区的引用(通过ManagedSlice)。这是有道理的:如果您使用堆栈分配的缓冲区创建RingBuffer,则缓冲区必须至少与RingBuffer 一样长。

    在旧版本的“书”中有一个标题为“Advanced Lifetimes”的部分。我在较新的版本中找不到它,但我发现它有助于理解这一点。您可能还想参考 rust 参考部分“Trait and lifetime bounds

    【讨论】:

      【解决方案3】:

      T: 'a 应该读作 "T 的边界是 'a" 而不是 "T 的生命周期是 'a"

      另外,T 包括所有可能的类型,包括具有生命周期的引用类型。 &amp;str&amp;i32 等都是T 中的有效类型。此外,要使用示例的简化版本,您可以拥有一个在生命周期内通用的拥有类型,因为它包含引用类型,如下所示:

      struct Ref<'a, T: 'a>(&'a T);
      

      该结构对'aT 是通用的,因为它可以保存&amp;'a T 引用。

      还有一点:&amp;'a T 需要T: 'a,因为T'a 有效,它必须比'a 寿命长。例如,编译器&amp;'static Ref&lt;'a, i32&gt; 会拒绝这种类型的构造,因为如果Ref 仅对'a 有效,我们就不能将'static 引用到它。

      【讨论】:

        猜你喜欢
        • 2014-08-01
        • 1970-01-01
        • 2021-05-24
        • 1970-01-01
        • 2014-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多