新类型索引是证明

主要观点:

  • 在 Rust 中,解决复杂所有权问题的方法是使用新类型索引,可将其视为关于引用对象的证明。
  • 新类型索引不仅是绕过所有权约束的方式,还能组合成具有合理意义的复合索引类型,其语义可继承子组件的语义。
  • 以编译器中的类型定义为例,通过新类型索引来准确表示和操作不同的声明及相关数据。

关键信息:

  • 2015 年 Niko Matsakis 发布关于在 Rust 中使用向量索引建模图的最早帖子,2018 年 Matklad 指出std::ops::Index特质可提供此模式的统一接口。
  • 以环境结构体Env为例,包含FunIdTypeId等,不同类型声明有多种子类型。
  • 指针和引用的概念,引用不能为 null,是存在的证明。FunId类似引用,能证明FunDecl的存在及读取权限。
  • 定义DeclIdDeclRef来处理不同声明类型,通过匹配实现获取声明的方法,DeclId对应逻辑或。
  • (TypeId, FunId)表示逻辑与,可组合新类型索引。
  • 对于ConstrId,需确定其父TypeDeclAdtDecl,创建AdtId类型来证明,从而正确实现获取ConstrDecl的方法。

重要细节:

  • 所有关于新类型索引的讨论基于一个隐含假设,即任何时候最多只有一个Env,若有多个Env可能导致错误。
  • 示例代码中get_funget_type等方法使用Option::unwrap,若访问器方法出错则创建TypeIdFunId时已出错。
  • 在处理ConstrId时,由于TypeId不能确定TypeDecl的变体,需创建AdtId来证明是AdtDecl
  • 提及[salsa](https://crates.io/crates/salsa) crate 是此技术的较大实现示例,其文档有相关概述。
  • 注释中对一些观点进行补充说明,如关于Option::unwrapOption::unwrap_unchecked的选择,以及(TypeId, FunId)顺序无关等。
阅读 15
0 条评论