Rust:官方迭代器大全

一、for 和迭代器

先看一段代码:

fn main() {
    for x in [1, 2, 3, 4, 5] {
        println!("{:?}", x);
    }
}
======== cargorun ========
1
2
3
4
5

如果 for 语句只能用于数组,那就太可惜了。我们看一下 Vec 类型:

fn main() {
    let list: Vec<i32> = vec![1, 2, 3, 4, 5];
    for x in list {
        println!("{:?}", x);
    }
}
======== cargorun ========
1
2
3
4
5

OK!
那么,我自己编写的数据类型能否这样用呢?
看代码:

struct MyList {
    list: [i32; 5],
}
fn main() {
    let list = MyList {
        list: [1, 2, 3, 4, 5],
    };
    for x in list {
        println!("{:?}", x);
    }
}
======== cargorun ========
8 |     for x in list {
  |              ^^^^ `MyList` is not an iterator

错误信息说,MyList 不是迭代器。原来,for 循环是和迭代器协同工作的。如果想让 MyList 用于 for 循环,必须实现迭代特性。

二、编写自己的迭代器

通过实现 Trait Iterator,可以编写自己的迭代器。

struct MyList {
    list: [i32; 5],
    index: usize,
}
impl MyList {
    fn from(list: [i32; 5]) -> Self {
        Self {
            list: list,
            index: 0,
        }
    }
}
impl Iterator for MyList {
    type Item = i32;
    fn next(&mut self) -> Option<Self::Item> {
        if self.index < 5 {
            let result = self.list[self.index];
            self.index += 1;
            return Some(result);
        } else {
            return None;
        }
    }
}
fn main() {
    let list = MyList::from([1, 2, 3, 4, 5]);
    for x in list {
        println!("{:?}", x);
    }
}
======== cargorun ========
1
2
3
4
5

三、iter() 迭代器

一般而言,Vec、HashMap 等类型通过方法 iter()、iter_mut() 等方法把自己转换成迭代器。下面我们也写一个 iter() 函数。

struct MyList {
    list: [i32; 5],
}

struct MyListIterator<'a> {
    index: i32,
    owner: &'a MyList,
}

impl Iterator for MyListIterator<'_> {
    type Item = i32;
    fn next(&mut self) -> Option<Self::Item> {
        self.index += 1;
        if self.index < 5 {
            Some(self.owner.list[self.index as usize])
        } else {
            None
        }
    }
}

impl MyList {
    fn iter(&self) -> MyListIterator {
        MyListIterator {
            index: -1,
            owner: self,
        }
    }
}
fn main() {
    let list = MyList {
        list: [1, 2, 3, 4, 5],
    };
    for x in list.iter() {
        println!("{:?}", x);
    }
}
======== cargorun ========
1
2
3
4
5

四、Rust 系统内置迭代器

Trait Iterator 自身定义了许多迭代器,这里给一个清单,具体可以参见 Rust 源代码 iterator.rs 注释说明。

名称声明用途
size_hintfn size_hint(&self) -> (usize, Option<usize>)返回迭代器剩余长度的界限。
countfn count(self) -> usize消费迭代器,计算迭代次数并返回它。
lastfn last(self) -> Option<Self::Item>消费迭代器,返回最后一个元素。
nthfn nth(&mut self, n: usize) -> Option<Self::Item>返回迭代器的第n个元素。
step_byfn step_by(self, step: usize) -> StepBy<Self>创建一个迭代器,该迭代器从同一点开始,但在每次迭代时按给定的数量步进。
chainfn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>创建两个迭代器,并按顺序在这两个迭代器上创建一个新的迭代器。
zipfn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>将两个迭代器“向上拉”成一对迭代器。
interspersefn intersperse(self, separator: Self::Item) -> Intersperse<Self>创建一个新迭代器,将分隔符的副本放置在原始迭代器的相邻项之间。
intersperse_withfn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>创建一个新的迭代器,将由分隔符生成的项放置在原始迭代器的相邻项之间。
mapfn map<B, F>(self, f: F) -> Map<Self, F>获取一个闭包并创建一个迭代器,该迭代器对每个元素调用该闭包。
for_eachfn for_each<F>(self, f: F)对迭代器的每个元素调用闭包。
filterfn filter<P>(self, predicate: P) -> Filter<Self, P>创建一个迭代器,该迭代器使用闭包来确定是否应生成元素。
filter_mapfn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>创建一个同时过滤和映射的迭代器。
enumeratefn enumerate(self) -> Enumerate<Self>创建一个迭代器,该迭代器给出当前迭代计数和下一个值。
peekablefn peekable(self) -> Peekable<Self>创建一个迭代器,可以使用[peek]和[peek_mut]方法查看迭代器的下一个元素,而无需使用它。有关更多信息,请参阅他们的文档。
skip_whilefn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>创建一个迭代器,该迭代器基于谓词[跳过]元素。
take_whilefn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>创建一个迭代器,该迭代器根据谓词生成元素。
map_whilefn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>创建一个迭代器,该迭代器基于谓词和映射生成元素。
skip fn skip(self, n: usize) -> Skip<Self>创建跳过前n个元素的迭代器。
takefn take(self, n: usize) -> Take<Self>创建一个迭代器,该迭代器生成前n个元素,如果基础迭代器结束得更早,则生成的元素更少。
scanfn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>类似于[fold]的迭代器适配器,它保存内部状态并生成新的迭代器。
flat_mapfn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>创建一个迭代器,其工作方式类似于map,但会展平嵌套结构。
flattenfn flatten(self) -> Flatten<Self>创建一个迭代器,用于展平嵌套结构。
fuse fn fuse(self) -> Fuse<Self>创建一个迭代器,该迭代器在第一个None之后结束。
inspectfn inspect<F>(self, f: F) -> Inspect<Self, F>对迭代器的每个元素执行某些操作,并传递值。
by_reffn by_ref(&mut self) -> &mut Self借用迭代器,而不是消费它。
collectfn collect<B: FromIterator<Self::Item>>(self) -> B将迭代器转换为集合。
partition fn partition<B, F>(self, f: F) -> (B, B)消费一个迭代器,从中创建两个集合。
partition_in_place fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize根据给定的谓词对迭代器的元素进行适当的重新排序,使所有返回true的元素优先于所有返回false的元素。返回找到的true元素数。
is_partitionedfn is_partitioned<P>(mut self, mut predicate: P) -> bool检查此迭代器的元素是否根据给定谓词进行了分区,以便所有返回true的元素优先于所有返回false的元素。
try_foldfn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R一种迭代器方法,只要函数成功返回,就会应用它,生成一个最终值。
try_for_eachfn try_for_each<F, R>(&mut self, f: F) -> R一种迭代器方法,对迭代器中的每个项应用一个易出错函数,在第一个错误处停止并返回该错误
foldfn fold<B, F>(mut self, init: B, mut f: F) -> B通过应用操作将每个元素折叠到累加器中,返回最终结果。
reducefn reduce<F>(mut self, f: F) -> Option<Self::Item>通过反复应用缩减操作,将元素缩减为单个元素。
allfn all<F>(&mut self, f: F) -> bool测试迭代器的每个元素是否与谓词匹配。
anyfn any<F>(&mut self, f: F) -> bool测试迭代器的任何元素是否与谓词匹配。
findfn find<P>(&mut self, predicate: P) -> Option<Self::Item>搜索迭代器中满足谓词的元素。
find_mapfn find_map<B, F>(&mut self, f: F) -> Option<B>将函数应用于迭代器的元素,并返回第一个非 none 结果。
try_findfn try_find<F, R, E>(&mut self, f: F) -> Result<Option<Self::Item>, E>将函数应用于迭代器的元素,并返回第一个真结果或第一个错误。
positionfn position<P>(&mut self, predicate: P) -> Option<usize>在迭代器中搜索元素,并返回其索引。
rpositionfn rposition<P>(&mut self, predicate: P) -> Option<usize>从右边搜索迭代器中的元素,并返回其索引。
maxfn max(self) -> Option<Self::Item>
minfn min(self) -> Option<Self::Item>
max_by_keyfn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>返回指定函数中给出最大值的元素。
max_byfn max_by<F>(self, compare: F) -> Option<Self::Item>返回相对于指定比较函数给出最大值的元素。
min_by_keyfn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
min_byfn min_by<F>(self, compare: F) -> Option<Self::Item>
revfn rev(self) -> Rev<Self>反转迭代器的方向。
unzipfn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)将成对的迭代器转换为一对容器。
copied fn copied<'a, T: 'a>(self) -> Copied<Self>创建一个迭代器,复制它的所有元素。
clonedfn cloned<'a, T: 'a>(self) -> Cloned<Self>创建一个迭代器,[clone]复制它的所有元素。
cycle fn cycle(self) -> Cycle<Self>无休止地重复迭代器。
sumfn sum<S>(self) -> S
productfn product<P>(self) -> P迭代整个迭代器,将所有元素相乘。
cmpfn cmp<I>(self, other: I) -> Ordering从词典的角度比较这个迭代器和另一个迭代器的元素。
cmp_by fn cmp_by<I, F>(mut self, other: I, mut cmp: F) -> Ordering根据指定的比较函数,按字典顺序将该迭代器的元素与另一迭代器的元素进行比较。
partial_cmpfn partial_cmp<I>(self, other: I) -> Option<Ordering>从词典的角度比较这个迭代器和另一个迭代器的元素。
partial_cmp_byfn partial_cmp_by<I, F>(mut self, other: I, mut partial_cmp: F) -> Option<Ordering>根据指定的比较函数,按字典顺序将该迭代器的元素与另一迭代器的元素进行比较。
eqfn eq<I>(self, other: I) -> bool确定此迭代器的元素是否与其他迭代器的元素相等。
eq_byfn eq_by<I, F>(mut self, other: I, mut eq: F) -> bool确定此迭代器的元素相对于指定的相等函数是否与另一个迭代器的元素相等。
nefn ne<I>(self, other: I) -> bool确定此迭代器的元素是否与其他迭代器的元素不相等。
ltfn lt<I>(self, other: I) -> bool
lefn le<I>(self, other: I) -> bool
gtn gt<I>(self, other: I) -> bool
gefn ge<I>(self, other: I) -> bool
is_sortedfn is_sorted(self) -> bool
is_sorted_by fn is_sorted_by<F>(mut self, compare: F) -> bool
is_sorted_by_keyfn is_sorted_by_key<F, K>(self, f: F) -> bool
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许野平

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值