这是一篇关于自引用类型的博客文章,主要内容如下:
- 动机示例:以
async {}
和Future
为例,展示自引用类型在异步编程中的应用,如在async
块中借用局部变量跨.await
点时,会创建自引用状态机,存储具体值和对该值的引用,编译器会对其进行去糖处理,生成GivePatsFuture
结构体等。 - 自引用生命周期:在动机示例中的
GivePatsFuture
结构体中,name
字段的生命周期未被显式指定,因为编译器在代码生成阶段已经检查过生命周期,目前人们正在努力添加可写的“未检查生命周期”,更好的是能描述“已检查生命周期”,这将使编写自引用结构体更方便。 - 就地构造类型:为使
'self
有效,需要保证值在内存中不移动,目前使用Pin
的方式不够优雅,理想情况下应让类型描述如何在内部就地构造自己,避免外部Pin::new_unchecked
调用,可通过类似“超级引”(super let
)的方式来实现,虽然目前只是假设,但能让函数体更易读。 - 转换为不可移动类型:为使异步编程更灵活,需要将类型分为可自由移动和不可移动两种,通过
IntoFuture
和Future
两个类型来实现,在构造不可移动类型时,先构造可自由移动的类型,准备完成后再转换为不可移动类型。 - 不可移动类型:为摆脱
Pin
,引入新的内置自动特质Move
,用于告知编译器类型是否可移动,通过添加!Move
实现不可移动类型,修改相关函数签名,使异步编程更方便,同时考虑内部可变性等问题。 - 重新设计的动机示例:将之前的示例用新的特性进行重写,包括
'self
生命周期、!Move
实现、省略Pin
以及就地构造类型等,展示自引用类型在异步编程中的实际应用。 - 分阶段初始化:介绍自引用类型的另一个方面——分阶段初始化,当需要初始化自引用时,不能一次性构建整个类型,而应分阶段进行,通过
super let
注释来指示在调用者的作用域中放置部分初始化的对象。 - 从 Pin 迁移到 Move:讨论从现有的基于
Pin
的 API 迁移到新的基于Move
的系统的问题,需要创建新的特质并提供桥接实现,同时要注意兼容性和逐步引入新特性。 - 使不可移动类型可移动:介绍在 Rust 中支持可移动的不可移动类型的方法,类似于 C++的移动构造函数,通过引入
Relocate
特质和relocate
方法来实现,需要解决一些相关的问题。 - 进一步阅读:提供了一些相关的阅读资源,包括
Pin
的 RFC、关于异步内部的系列博客和演讲、支持 C++移动构造函数的 crate 等,这些资源对于深入理解自引用类型和相关概念很有帮助。 - 结论:将“自引用类型”分解为四个组成部分,即
'unsafe
和'self
生命周期、“超级引”、可选的-> super Type
符号以及新的Move
自动特质,通过Move
可以模拟Pin + Unpin
系统,目前人们普遍不喜欢Pin
,应避免在标准库中引入更多基于Pin
的 API,逐步解决“不可移动类型”的问题。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。