如何更简便返回带多Iterator特性的impl Iterator<Item = T>?
Rust迭代器返回的
impl Trait优化方案及性能问题 1. 无需逐个声明子trait的返回方式
- 自定义复合迭代器trait:借助trait继承组合所需特性,避免重复声明。先定义一个继承了所有目标迭代器trait的新trait,再为所有符合条件的类型自动实现它,后续返回时直接使用这个复合trait即可:
use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator}; // 组合所需迭代器特性的复合trait pub trait FullIterator<T>: Iterator<Item = T> + DoubleEndedIterator + ExactSizeIterator + FusedIterator {} // 为所有满足条件的迭代器自动实现该复合trait impl<T, I> FullIterator<T> for I where I: Iterator<Item = T> + DoubleEndedIterator + ExactSizeIterator + FusedIterator {} // 返回impl FullIterator<T>即可一次性包含所有特性 fn my_iterator() -> impl FullIterator<i32> { vec![1,2,3].into_iter() }
如果不需要导出这个复合trait,可将其放在私有模块中,返回签名使用私有路径即可,不影响调用方使用迭代器方法。
- 紧凑的多trait约束写法:无需定义新trait,直接在
impl Trait后并列所有需要的trait,语法更简洁,适合无需复用约束的场景:
fn my_iterator() -> impl Iterator<Item = i32> + DoubleEndedIterator + ExactSizeIterator + FusedIterator { vec![1,2,3].into_iter() }
2. 未声明子trait的性能影响
完全没有性能损失。impl Trait采用静态分发,编译期编译器已经明确底层迭代器的具体类型,只是返回签名的约束会限制调用方使用子trait的方法,但实际执行代码和直接返回具体迭代器类型完全一致,不会产生动态分发的额外开销。
比如,若返回签名仅写impl Iterator<Item = i32>,但底层是实现了所有子trait的Vec<i32>::IntoIter,编译时编译器知晓具体类型,性能和直接返回Vec<i32>::IntoIter无差异,只是调用方无法调用rev()这类子trait方法。
内容的提问来源于stack exchange,提问作者scottwillmoore
相关产品推荐
相关产品推荐

