Rust 生命周期标注积累

Rust 生命周期标注是相当难学的。首先这个概念不方便用语言描述,以至于对"生命周期标注"的精辟总结往往是有歧义的,新手看到时容易纠结,不知道怎么理解对,这增加了学习的难度。其次新手不容易想象"生命周期标注"的使用场景,这种场景也比较复杂,需要学习者对 Rust 生命周期等基础的概念有深刻的理解。而且"生命周期标注"的语义可能是多样的,在不同场景下不完全相同,这意味着这个概念本身内容较多,注定要花更多的时间学习。最后,理解"生命周期标注"最终是要理解 Rust 编译器的行为,这种程序行为是很难用自然语言总结全面、准确的,所以在学习过程中总会觉得存在没有理解清楚的特殊情况。

我曾经多次下定决心要搞懂生命周期标注,但最终都失败了。最近我又遇到了这个概念,打算积累下我实际编程中遇到的情况,不强求总结出任何理解。

结构体定义中的生命周期标识

举一个来自星绽的例子

rust 复制代码
/// The result of a query over the VM space.
pub enum VmQueriedItem<'a> {
    /// The current slot is mapped, the frame within is allocated from the
    /// physical memory.
    MappedRam {
        /// The mapped frame.
        frame: FrameRef<'a, dyn AnyUFrameMeta>,
        /// The property of the slot.
        prop: PageProperty,
    },
    /// The current slot is mapped, the frame within is allocated from the
    /// MMIO memory.
    MappedIoMem {
        /// The physical address of the corresponding I/O memory.
        paddr: Paddr,
        /// The property of the slot.
        prop: PageProperty,
    },
}

/// A struct that can work as `&'a Frame<M>`.
pub struct FrameRef<'a, M: AnyFrameMeta + ?Sized> {
    inner: ManuallyDrop<Frame<M>>,
    _marker: PhantomData<&'a Frame<M>>,
}

这里 pub enum VmQueriedItem<'a> 中的 'a 是生命周期标识,表示 VmQueriedItem 的生命周期。此时 'a 是一个变量,不知道具体的生命周期是什么。但我们知道,VmQueriedItem 和 其字段 FrameRef 拥有同样的生命周期,而 FrameRef 和其字段 PhantomData<&'a Frame<M>> 拥有同样的生命周期。这里的字段一定是引用类型或者包含引用类型,我们关注引用类型的生命周期是为了避免悬垂引用。

当创建 VmQueriedItem 类型时,为了构造其字段,我们会传入引用,传入的引用的实际生命周期决定了 'a 的值,编译器通过 'a 的标识知道所构造的 VmQueriedItem 类型的值的生命周期不能超过 'a(否则 VmQueriedItem 类型的值还活着而其中的引用类型已死)。编译器在编译时会检查这个 VmQueriedItem 类型的值有没有在超过 'a 生命周期的时候被使用,如果有则编译时报错。

相关推荐
Ada's5 小时前
【计算机基础系列】003:Python数据结构
开发语言·数据结构·python
2601_962885725 小时前
如何用 Python 计算 TRIX 三重指数平滑均线指标?
开发语言·python
还卿一钵无情泪6 小时前
Unsloth 微调 构建自己的大模型 没有GPU也能微调
linux·开发语言·人工智能·python·大模型·nlp·unsloth
倔强的石头1067 小时前
应用账号最小权限实践:读写账号、报表账号、运维账号分层
java·运维·开发语言
传人once7 小时前
页面中心圆圈放大效果如何写
开发语言·javascript·ecmascript
NeilYuen7 小时前
【C++】STL源码仿写(二):vector
开发语言·c++
蜗牛互联网8 小时前
Python消费Responses SSE事件:增量文本、超时与取消
java·开发语言·人工智能·后端·python
weixin_307779138 小时前
C++代码实现MATLAB中的crossval函数功能
开发语言·c++·算法·matlab
ttwuai9 小时前
Go后台管理系统开源项目:4个官方仓库怎么追溯和核验
开发语言·golang·开源
谢亮_vipxieliang9 小时前
Go Worker Pool 设计——从原理到生产级实现
开发语言·后端·golang