每一个迭代器变体的调查

这篇博客全面介绍了 Rust 中的各种迭代器变体,包括基础迭代器、有界迭代器、融合迭代器、线程安全迭代器、动态兼容迭代器、双向迭代器、查找迭代器、编译时迭代器、借出迭代器、带返回值的迭代器、带 next 参数的迭代器、短路迭代器、地址敏感迭代器、保证析构的迭代器、异步迭代器和并发迭代器等。

基础迭代器(Base Iterator)Iterator trait 表示迭代的有状态组件,IntoIterator 表示类型可被迭代的能力,两者紧密相关。基础的 Iterator trait 缺乏一些高级特性,如阻塞、不能在编译时评估、严格顺序等。

有界迭代器(Bounded Iterator):基础的 Iterator trait 代表潜在无限(无界)的项序列,ExactSizeIteratorTrustedLen 这两个 Iterator 的子 trait 可保证迭代器是有界的。ExactSizeIterator 能返回迭代器的精确剩余长度,但不能依赖其值一定正确;TrustedLen 是不安全的实现,可用于保证安全不变量,使用时可省略边界检查。

融合迭代器(Fused Iterator):大多数标准库中的迭代器实现了 FusedIterator trait,它保证一旦迭代器返回 None,后续调用 next 也将继续返回 None。对于未融合的迭代器,可调用 Iterator::fuse 组合子来保证融合行为。FusedIterator 的设计基于 Option::None 的幂等性。

线程安全迭代器(Thread-Safe Iterator):线程安全迭代器通过将 SendSync 自动 trait 与 Iterator trait 组合得到,无需专门的 SendIteratorSyncIterator trait。在使用时,可通过组合 trait 来表达意图,如 fn thread_safe_sink(iter: impl IntoIterator + Send)

动态兼容迭代器(Dyn-Compatible Iterator)IteratorIntoIterator trait 本身是动态兼容的,可用于创建 trait 对象。但一些迭代器组合子如 count 有额外的 Self: Sized 边界。

双向迭代器(Double-Ended Iterator)DoubleEndedIterator trait 允许从迭代器的两端获取元素,通过 next_back 方法实现从后端获取元素,并且有一些基于此的新方法如 rfoldrfind

查找迭代器(Seeking Iterator)IteratorRead trait 都提供了流式迭代的抽象,但 Iterator 没有控制底层游标(cursor)的机制。借鉴 C++ 的 random_access_iterator 概念,可创建一个 SeekingIterator 子 trait 来控制迭代器的游标。

编译时迭代器(Compile-Time Iterator):在 Rust 中,const {} 块可在编译时执行代码,但 Iterator trait 目前还不能在 const {} 块中调用。讨论了如何在编译时支持迭代,以及相关的 trait 声明和边界问题。

借出迭代器(Lending Iterator):标准库中的很多迭代器返回引用,但不能拥有所迭代的项。为了创建可拥有并通过引用返回项的迭代器,需要在迭代器的关联项类型中添加生命周期。

带返回值的迭代器(Iterator with a Return Value):当前的 Iterator trait 有关联类型 Item 映射到 yield 关键字,需要添加一个关联类型 Output 来表示逻辑返回值,next 函数需要能够返回三种状态。这会影响 for_each 等方法的返回类型和行为。

带 next 参数的迭代器(Iterator with a Next Argument):为了支持在迭代器中传递新值,Iterator::next 需要能够接受一个额外的参数 Args,类似于 "coroutine" 的功能。这会影响 for_each 等方法的签名和调用方式。

短路迭代器(Short-Circuiting Iterator):短路迭代器是 "iterator with return value" 的特殊情况,在遇到错误时立即停止执行。通过 try {} 块和 impl Try 来实现,需要在迭代器 trait 中添加相关的类型和方法。

地址敏感迭代器(Address-Sensitive Iterator):Rust 的生成器转换可能创建自引用类型,需要 "address-sensitive iterator" 来处理。可通过创建新 trait PinnedIterator 来改变 next 的自类型,但 Pin 存在一些问题。还讨论了关于 Iterator trait 的 (soft-)deprecation 方案。

保证析构的迭代器(Iterator Guaranteeing Destruct):通过引入新的自动 trait Leak,可以保证类型的析构函数一定会运行,类似于 thread::scope 的功能。

异步迭代器(Async Iterator)async 关键字可将函数体转换为状态机,Iterator trait 与 async 结合主要是在 next 方法前添加 async 前缀。还讨论了异步地址敏感迭代器和不同的异步迭代器 trait 的特点和问题。

并发迭代器(Concurrent Iterator)rayon crate 的 ParallelIterator trait 可实现并行迭代,处理项时使用操作系统线程,提高吞吐量,但要求所有消耗的项实现 Send。并发迭代与借出迭代互斥。

结论(Conclusion):总结了 17 种迭代器变体,指出 Iterator 是语言中最复杂的 trait 之一,是语言中各种特性的交汇点,需要在扩展和维护之间找到平衡,以解决语言中的问题并提高语言的能力和可扩展性。

阅读 10
0 条评论