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 生命周期的时候被使用,如果有则编译时报错。

相关推荐
caimouse1 小时前
mshtml/nsio.c 实现报告
c语言·开发语言
龙侠九重天1 小时前
C# 构建 AI Agent 系统 — 我的实践笔记
开发语言·人工智能·语言模型·自然语言处理·大模型·agent·智能体
SilentSamsara1 小时前
Pandas 工程化:多层索引、分组聚合与窗口函数的进阶用法
开发语言·python·青少年编程·pandas
何以解忧,唯有..1 小时前
Python 字符串完全指南:从基础到高级操作
开发语言·python
kiss strong1 小时前
自制请求工具
开发语言·python·lua
scan7241 小时前
短期记忆记忆存储在内存里,一个会话里的多轮对话
开发语言·c#
星栈2 小时前
Makepad UI 代码怎么读:别被语法吓住
前端·rust
程序员皮皮林2 小时前
Dubbo 的 SPI 和 JDK 的 SPI 有什么区别?
java·开发语言·dubbo
是多巴胺不是尼古丁2 小时前
java‘期末复习--多态
java·开发语言