这篇文章提出了一种名为 MinPin 的船只UnpinCell提案的变体,其目标是以“最小破坏性”的方式将Pin集成到语言中,特别是完全向后兼容的方式。
主要观点和关键信息:
设计决策:
- 使用
pinned关键字获取事物的固定变体,在类型、函数签名和表达式中有不同的用法。 - 修改
Droptrait 为fn drop(pinned &mut self),允许但不强制使用fn drop(&mut self)。 - 基于
Unpin的实现情况,规定从pinned &mut S引用中进行字段投影的规则。 - 存在一个总是实现
Unpin的类型Unpinnable<T>。
- 使用
设计公理:
Pin是 Rust 语言的一部分,应得到一流的支持。Pin有其特定的使用场景,应与其他部分隔离。Pin应具有零概念成本,不影响普通代码。- 显式操作是可能的,应优先使用显式操作。
- 保持向后兼容性,现有代码应继续编译和工作。
常见问题解答:
- 使用 MinPin 时,对于大多数类型,使用
&self和&mut self即可;对于关心固定的类型,应显式实现!Unpin,并根据方法的读写性质选择&mut self或pinned &mut self。 - MinPin 与 UnpinCell 的主要区别在于处理未知是否为
Unpin的泛型结构体时的规则,MinPin 要求显式的!Unpin实现,而 UnpinCell 基于自动 trait 机制。 - 对于更喜欢 MinPin 还是 UnpinCell ,作者认为两者各有优劣,取决于具体的设计需求和使用场景。
- “
Pin是其自己的世界”意味着T:!Unpin类型在固定前后有不同的访问方式,限制了语言的互操作性,但对于某些领域(如 futures)来说并非不可接受。 Overwrite会使固定成为&mut能力的超集,有助于使Pin感觉像语言的平滑集成部分,但如果Overwrite有其合理性,不应基于Pin本身,而应基于不可变字段。- 采用
pinned &mut而不是&pin mut作为语法,是为了适应Pin<Box<T>>等情况,并且避免pin!宏带来的尴尬。 - 以
MaybeDone和Join为例展示了 MinPin 在实际代码中的应用,包括Drop的处理和 pin-projection 的使用。 Drop的当前签名与固定后的类型访问限制存在矛盾,需要根据类型的Unpin实现情况进行处理,目前的设计将类型分为三类。- 对于
Overwrite的向前兼容性,若采用Overwrite,则需进行相关的命名更改和限制,以保证固定保证的完整性。
- 使用 MinPin 时,对于大多数类型,使用
重要细节:
- 在处理未知是否为
Unpin的泛型结构体时,MinPin 的规则更加严格,需要显式的!Unpin实现,而 UnpinCell 基于自动 trait 机制。 - 在
Drop的处理中,根据类型的Unpin实现情况,分为不同的类别,以处理固定后与Drop方法的兼容性问题。 - 在使用 MinPin 时,对于大多数类型,无需关心
Pin,但对于关心固定的类型,需要显式处理!Unpin和pinned &mut self。 Overwrite的采用会使代码中使用std::mem::replace或std::mem::swap的模式发生变化,可能需要使用显式的Unpinnable包装器。
总结来说,MinPin 是一种在 Rust 语言中集成Pin的尝试,旨在以最小的破坏性实现向后兼容,并在设计中考虑了各种因素,如Pin的特性、与其他语言特性的交互等。同时,与 UnpinCell 相比,MinPin 在处理未知Unpin类型时有不同的规则,并且对Overwrite的采用也有相应的考虑。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。