这篇博客全面介绍了 Rust 中的各种迭代器变体,包括基础迭代器、有界迭代器、融合迭代器、线程安全迭代器、动态兼容迭代器、双向迭代器、查找迭代器、编译时迭代器、借出迭代器、带返回值的迭代器、带 next 参数的迭代器、短路迭代器、地址敏感迭代器、保证析构的迭代器、异步迭代器和并发迭代器等。
基础迭代器(Base Iterator):Iterator
trait 表示迭代的有状态组件,IntoIterator
表示类型可被迭代的能力,两者紧密相关。基础的 Iterator
trait 缺乏一些高级特性,如阻塞、不能在编译时评估、严格顺序等。
有界迭代器(Bounded Iterator):基础的 Iterator
trait 代表潜在无限(无界)的项序列,ExactSizeIterator
和 TrustedLen
这两个 Iterator
的子 trait 可保证迭代器是有界的。ExactSizeIterator
能返回迭代器的精确剩余长度,但不能依赖其值一定正确;TrustedLen
是不安全的实现,可用于保证安全不变量,使用时可省略边界检查。
融合迭代器(Fused Iterator):大多数标准库中的迭代器实现了 FusedIterator
trait,它保证一旦迭代器返回 None
,后续调用 next
也将继续返回 None
。对于未融合的迭代器,可调用 Iterator::fuse
组合子来保证融合行为。FusedIterator
的设计基于 Option::None
的幂等性。
线程安全迭代器(Thread-Safe Iterator):线程安全迭代器通过将 Send
和 Sync
自动 trait 与 Iterator
trait 组合得到,无需专门的 SendIterator
或 SyncIterator
trait。在使用时,可通过组合 trait 来表达意图,如 fn thread_safe_sink(iter: impl IntoIterator + Send)
。
动态兼容迭代器(Dyn-Compatible Iterator):Iterator
和 IntoIterator
trait 本身是动态兼容的,可用于创建 trait 对象。但一些迭代器组合子如 count
有额外的 Self: Sized
边界。
双向迭代器(Double-Ended Iterator):DoubleEndedIterator
trait 允许从迭代器的两端获取元素,通过 next_back
方法实现从后端获取元素,并且有一些基于此的新方法如 rfold
和 rfind
。
查找迭代器(Seeking Iterator):Iterator
和 Read
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 之一,是语言中各种特性的交汇点,需要在扩展和维护之间找到平衡,以解决语言中的问题并提高语言的能力和可扩展性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。