Rust 中的安全单元字段投影

2020 年 1 月 5 日,作者发布了dioptre crate,这是Driveyard的最新添加项。dioptre是用于结构字段反射的轻量级 proc-macro。本文主题是基于此功能构建的技巧 - Cell字段投影,从Cell<Struct>Cell<Field>

内部可变性

Rust 中严格的指针别名规则导致人们在“与借用检查器斗争”,但 Rust 也提供了内部可变性,以各种方式放宽&T引用的不可变性,同时仍保留内存安全性。最常见的内部可变性例子是MutexOnceCell,Rust 初学者常被引导使用RefCell来处理&T/&mut T规则。

Cell 及其升级

Cell类型最初提供简单的内部可变性,可包裹Copy类型并提供getset方法。RFC 1651 使其可用于非Copy类型,RFC 1789 使其支持对包裹对象内部的引用,提供了从&Cell<[E]>&[Cell<E>]的转换。

字段投影

RFC 1789 的Cell索引操作是一种投影形式,可从整体中提取对象的一部分。例如在处理Point数组时,没有内部可变性会导致编译错误,通过将&mut [Point]转换为&Cell<[Point]>,再利用dioptre进行字段投影可解决问题,如j.project(Point::x).set(...)。同时,由于可拥有对结构的多个共享引用,无需特殊支持即可获取不相交字段的引用,如split(point: &Cell<Point>) -> (&Cell<f32>, &Cell<f32>)

阅读 11
0 条评论