Trait core::iter::Iterator1.0.0[][src]

#[must_use = "iterators are lazy and do nothing unless consumed"]
pub trait Iterator {
    type Item;
Show methods fn next(&mut self) -> Option<Self::Item>; fn size_hint(&self) -> (usize, Option<usize>) { ... }
fn count(self) -> usize
    where
        Self: Sized
, { ... }
fn last(self) -> Option<Self::Item>
    where
        Self: Sized
, { ... }
fn advance_by(&mut self, n: usize) -> Result<(), usize> { ... }
fn nth(&mut self, n: usize) -> Option<Self::Item> { ... }
fn step_by(self, step: usize) -> StepBy<Self>
Notable traits for StepBy<I>
impl<I> Iterator for StepBy<I> where
    I: Iterator
type Item = I::Item;

    where
        Self: Sized
, { ... }
fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
Notable traits for Chain<A, B>
impl<A, B> Iterator for Chain<A, B> where
    A: Iterator,
    B: Iterator<Item = A::Item>, 
type Item = A::Item;

    where
        Self: Sized,
        U: IntoIterator<Item = Self::Item>
, { ... }
fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
Notable traits for Zip<A, B>
impl<A, B> Iterator for Zip<A, B> where
    A: Iterator,
    B: Iterator
type Item = (A::Item, B::Item);

    where
        Self: Sized,
        U: IntoIterator
, { ... }
fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
Notable traits for Intersperse<I>
impl<I> Iterator for Intersperse<I> where
    I: Iterator,
    I::Item: Clone
type Item = I::Item;

    where
        Self: Sized,
        Self::Item: Clone
, { ... }
fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
Notable traits for IntersperseWith<I, G>
impl<I, G> Iterator for IntersperseWith<I, G> where
    I: Iterator,
    G: FnMut() -> I::Item
type Item = I::Item;

    where
        Self: Sized,
        G: FnMut() -> Self::Item
, { ... }
fn map<B, F>(self, f: F) -> Map<Self, F>
Notable traits for Map<I, F>
impl<B, I: Iterator, F> Iterator for Map<I, F> where
    F: FnMut(I::Item) -> B, 
type Item = B;

    where
        Self: Sized,
        F: FnMut(Self::Item) -> B
, { ... }
fn for_each<F>(self, f: F)
    where
        Self: Sized,
        F: FnMut(Self::Item)
, { ... }
fn filter<P>(self, predicate: P) -> Filter<Self, P>
Notable traits for Filter<I, P>
impl<I: Iterator, P> Iterator for Filter<I, P> where
    P: FnMut(&I::Item) -> bool, 
type Item = I::Item;

    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool
, { ... }
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
Notable traits for FilterMap<I, F>
impl<B, I: Iterator, F> Iterator for FilterMap<I, F> where
    F: FnMut(I::Item) -> Option<B>, 
type Item = B;

    where
        Self: Sized,
        F: FnMut(Self::Item) -> Option<B>
, { ... }
fn enumerate(self) -> Enumerate<Self>
Notable traits for Enumerate<I>
impl<I> Iterator for Enumerate<I> where
    I: Iterator
type Item = (usize, <I as Iterator>::Item);

    where
        Self: Sized
, { ... }
fn peekable(self) -> Peekable<Self>
Notable traits for Peekable<I>
impl<I: Iterator> Iterator for Peekable<I> type Item = I::Item;

    where
        Self: Sized
, { ... }
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
Notable traits for SkipWhile<I, P>
impl<I: Iterator, P> Iterator for SkipWhile<I, P> where
    P: FnMut(&I::Item) -> bool, 
type Item = I::Item;

    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool
, { ... }
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
Notable traits for TakeWhile<I, P>
impl<I: Iterator, P> Iterator for TakeWhile<I, P> where
    P: FnMut(&I::Item) -> bool, 
type Item = I::Item;

    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool
, { ... }
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
Notable traits for MapWhile<I, P>
impl<B, I: Iterator, P> Iterator for MapWhile<I, P> where
    P: FnMut(I::Item) -> Option<B>, 
type Item = B;

    where
        Self: Sized,
        P: FnMut(Self::Item) -> Option<B>
, { ... }
fn skip(self, n: usize) -> Skip<Self>
Notable traits for Skip<I>
impl<I> Iterator for Skip<I> where
    I: Iterator
type Item = <I as Iterator>::Item;

    where
        Self: Sized
, { ... }
fn take(self, n: usize) -> Take<Self>
Notable traits for Take<I>
impl<I> Iterator for Take<I> where
    I: Iterator
type Item = <I as Iterator>::Item;

    where
        Self: Sized
, { ... }
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
Notable traits for Scan<I, St, F>
impl<B, I, St, F> Iterator for Scan<I, St, F> where
    I: Iterator,
    F: FnMut(&mut St, I::Item) -> Option<B>, 
type Item = B;

    where
        Self: Sized,
        F: FnMut(&mut St, Self::Item) -> Option<B>
, { ... }
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
Notable traits for FlatMap<I, U, F>
impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F> where
    F: FnMut(I::Item) -> U, 
type Item = U::Item;

    where
        Self: Sized,
        U: IntoIterator,
        F: FnMut(Self::Item) -> U
, { ... }
fn flatten(self) -> Flatten<Self>
Notable traits for Flatten<I>
impl<I, U> Iterator for Flatten<I> where
    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
    U: Iterator
type Item = U::Item;

    where
        Self: Sized,
        Self::Item: IntoIterator
, { ... }
fn fuse(self) -> Fuse<Self>
Notable traits for Fuse<I>
impl<I> Iterator for Fuse<I> where
    I: Iterator
type Item = <I as Iterator>::Item;

    where
        Self: Sized
, { ... }
fn inspect<F>(self, f: F) -> Inspect<Self, F>
Notable traits for Inspect<I, F>
impl<I: Iterator, F> Iterator for Inspect<I, F> where
    F: FnMut(&I::Item), 
type Item = I::Item;

    where
        Self: Sized,
        F: FnMut(&Self::Item)
, { ... }
fn by_ref(&mut self) -> &mut Self
    where
        Self: Sized
, { ... }
#[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] fn collect<B: FromIterator<Self::Item>>(self) -> B
    where
        Self: Sized
, { ... }
fn partition<B, F>(self, f: F) -> (B, B)
    where
        Self: Sized,
        B: Default + Extend<Self::Item>,
        F: FnMut(&Self::Item) -> bool
, { ... }
fn partition_in_place<'a, T: 'a, P>(self, predicate: P) -> usize
    where
        Self: Sized + DoubleEndedIterator<Item = &'a mut T>,
        P: FnMut(&T) -> bool
, { ... }
fn is_partitioned<P>(self, predicate: P) -> bool
    where
        Self: Sized,
        P: FnMut(Self::Item) -> bool
, { ... }
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> R,
        R: Try<Output = B>
, { ... }
fn try_for_each<F, R>(&mut self, f: F) -> R
    where
        Self: Sized,
        F: FnMut(Self::Item) -> R,
        R: Try<Output = ()>
, { ... }
fn fold<B, F>(self, init: B, f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item) -> B
, { ... }
fn reduce<F>(self, f: F) -> Option<Self::Item>
    where
        Self: Sized,
        F: FnMut(Self::Item, Self::Item) -> Self::Item
, { ... }
fn all<F>(&mut self, f: F) -> bool
    where
        Self: Sized,
        F: FnMut(Self::Item) -> bool
, { ... }
fn any<F>(&mut self, f: F) -> bool
    where
        Self: Sized,
        F: FnMut(Self::Item) -> bool
, { ... }
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool
, { ... }
fn find_map<B, F>(&mut self, f: F) -> Option<B>
    where
        Self: Sized,
        F: FnMut(Self::Item) -> Option<B>
, { ... }
fn try_find<F, R, E>(&mut self, f: F) -> Result<Option<Self::Item>, E>
    where
        Self: Sized,
        F: FnMut(&Self::Item) -> R,
        R: Try<Output = bool>,
        R: TryV2<Residual = Result<Infallible, E>>
, { ... }
fn position<P>(&mut self, predicate: P) -> Option<usize>
    where
        Self: Sized,
        P: FnMut(Self::Item) -> bool
, { ... }
fn rposition<P>(&mut self, predicate: P) -> Option<usize>
    where
        P: FnMut(Self::Item) -> bool,
        Self: Sized + ExactSizeIterator + DoubleEndedIterator
, { ... }
fn max(self) -> Option<Self::Item>
    where
        Self: Sized,
        Self::Item: Ord
, { ... }
fn min(self) -> Option<Self::Item>
    where
        Self: Sized,
        Self::Item: Ord
, { ... }
fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
    where
        Self: Sized,
        F: FnMut(&Self::Item) -> B
, { ... }
fn max_by<F>(self, compare: F) -> Option<Self::Item>
    where
        Self: Sized,
        F: FnMut(&Self::Item, &Self::Item) -> Ordering
, { ... }
fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
    where
        Self: Sized,
        F: FnMut(&Self::Item) -> B
, { ... }
fn min_by<F>(self, compare: F) -> Option<Self::Item>
    where
        Self: Sized,
        F: FnMut(&Self::Item, &Self::Item) -> Ordering
, { ... }
fn rev(self) -> Rev<Self>
Notable traits for Rev<I>
impl<I> Iterator for Rev<I> where
    I: DoubleEndedIterator
type Item = <I as Iterator>::Item;

    where
        Self: Sized + DoubleEndedIterator
, { ... }
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
    where
        FromA: Default + Extend<A>,
        FromB: Default + Extend<B>,
        Self: Sized + Iterator<Item = (A, B)>
, { ... }
fn copied<'a, T: 'a>(self) -> Copied<Self>
Notable traits for Copied<I>
impl<'a, I, T: 'a> Iterator for Copied<I> where
    I: Iterator<Item = &'a T>,
    T: Copy
type Item = T;

    where
        Self: Sized + Iterator<Item = &'a T>,
        T: Copy
, { ... }
fn cloned<'a, T: 'a>(self) -> Cloned<Self>
Notable traits for Cloned<I>
impl<'a, I, T: 'a> Iterator for Cloned<I> where
    I: Iterator<Item = &'a T>,
    T: Clone
type Item = T;

    where
        Self: Sized + Iterator<Item = &'a T>,
        T: Clone
, { ... }
fn cycle(self) -> Cycle<Self>
Notable traits for Cycle<I>
impl<I> Iterator for Cycle<I> where
    I: Clone + Iterator
type Item = <I as Iterator>::Item;

    where
        Self: Sized + Clone
, { ... }
fn sum<S>(self) -> S
    where
        Self: Sized,
        S: Sum<Self::Item>
, { ... }
fn product<P>(self) -> P
    where
        Self: Sized,
        P: Product<Self::Item>
, { ... }
fn cmp<I>(self, other: I) -> Ordering
    where
        I: IntoIterator<Item = Self::Item>,
        Self::Item: Ord,
        Self: Sized
, { ... }
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
    where
        Self: Sized,
        I: IntoIterator,
        F: FnMut(Self::Item, I::Item) -> Ordering
, { ... }
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
    where
        I: IntoIterator,
        Self::Item: PartialOrd<I::Item>,
        Self: Sized
, { ... }
fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
    where
        Self: Sized,
        I: IntoIterator,
        F: FnMut(Self::Item, I::Item) -> Option<Ordering>
, { ... }
fn eq<I>(self, other: I) -> bool
    where
        I: IntoIterator,
        Self::Item: PartialEq<I::Item>,
        Self: Sized
, { ... }
fn eq_by<I, F>(self, other: I, eq: F) -> bool
    where
        Self: Sized,
        I: IntoIterator,
        F: FnMut(Self::Item, I::Item) -> bool
, { ... }
fn ne<I>(self, other: I) -> bool
    where
        I: IntoIterator,
        Self::Item: PartialEq<I::Item>,
        Self: Sized
, { ... }
fn lt<I>(self, other: I) -> bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd<I::Item>,
        Self: Sized
, { ... }
fn le<I>(self, other: I) -> bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd<I::Item>,
        Self: Sized
, { ... }
fn gt<I>(self, other: I) -> bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd<I::Item>,
        Self: Sized
, { ... }
fn ge<I>(self, other: I) -> bool
    where
        I: IntoIterator,
        Self::Item: PartialOrd<I::Item>,
        Self: Sized
, { ... }
fn is_sorted(self) -> bool
    where
        Self: Sized,
        Self::Item: PartialOrd
, { ... }
fn is_sorted_by<F>(self, compare: F) -> bool
    where
        Self: Sized,
        F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>
, { ... }
fn is_sorted_by_key<F, K>(self, f: F) -> bool
    where
        Self: Sized,
        F: FnMut(Self::Item) -> K,
        K: PartialOrd
, { ... }
}
Expand description

用于处理迭代器的接口。

这是主要的迭代器 trait。 有关一般迭代器概念的更多信息,请参见 module-level documentation。 特别是,您可能想知道如何 implement Iterator

Associated Types

被迭代的元素的类型。

Required methods

推进迭代器并返回下一个值。

迭代完成后返回 None。 各个迭代器的实现可能选择恢复迭代,因此再次调用 next() 可能会或可能不会最终在某个时候开始再次返回 Some(Item)

Examples

基本用法:

let a = [1, 2, 3];

let mut iter = a.iter();

// 调用 next() 返回下一个值...
assert_eq!(Some(&1), iter.next());
assert_eq!(Some(&2), iter.next());
assert_eq!(Some(&3), iter.next());

// ... 然后,一旦结束,就再也没有。
assert_eq!(None, iter.next());

// 更多调用可能会也可能不会返回 `None`。在这里,他们总是会的。
assert_eq!(None, iter.next());
assert_eq!(None, iter.next());
Run

Provided methods

返回迭代器剩余长度的界限。

具体来说,size_hint() 返回一个元组,其中第一个元素是下界,第二个元素是上界。

返回的元组的后半部分是 Option<usize>。 这里的 None 表示没有已知的上限,或者该上限大于 usize

实现说明

没有强制要求迭代器实现产生声明数量的元素。buggy 迭代器的结果可能小于元素的下限,也可能大于元素的上限。

size_hint() 主要用于优化,例如为迭代器的元素保留空间,但不得信任,例如可以省略不安全代码中的边界检查。 size_hint() 的不正确实现不应导致违反内存安全性。

也就是说,该实现应提供正确的估计,因为否则将违反 trait 的协议。

默认实现返回 (0,None) 对任何迭代器都是正确的。

Examples

基本用法:

let a = [1, 2, 3];
let iter = a.iter();

assert_eq!((3, Some(3)), iter.size_hint());
Run

一个更复杂的示例:

// 介于 0 到 9 之间的偶数。
let iter = (0..10).filter(|x| x % 2 == 0);

// 我们可以从零迭代到十次。
// 不执行 filter() 就不可能知道它是 5。
assert_eq!((0, Some(10)), iter.size_hint());

// 让我们用 chain() 再添加五个数字
let iter = (0..10).filter(|x| x % 2 == 0).chain(15..20);

// 现在两个界限都增加了五个
assert_eq!((5, Some(15)), iter.size_hint());
Run

返回 None 作为上限:

// 无限迭代器没有上限,最大可能下限
let iter = 0..;

assert_eq!((usize::MAX, None), iter.size_hint());
Run

使用迭代器,计算迭代次数并返回它。

此方法将反复调用 next,直到遇到 None,并返回它看到 Some 的次数。 请注意,即使迭代器没有任何元素,也必须至少调用一次 next

溢出行为

该方法无法防止溢出,因此对具有超过 usize::MAX 个元素的迭代器的元素进行计数会产生错误的结果或 panics。

如果启用了调试断言,则将保证 panic。

Panics

如果迭代器具有多个 usize::MAX 元素,则此函数可能为 panic。

Examples

基本用法:

let a = [1, 2, 3];
assert_eq!(a.iter().count(), 3);

let a = [1, 2, 3, 4, 5];
assert_eq!(a.iter().count(), 5);
Run

使用迭代器,返回最后一个元素。

此方法将评估迭代器,直到返回 None。 这样做时,它会跟踪当前元素。 返回 None 之后,last() 将返回它看到的最后一个元素。

Examples

基本用法:

let a = [1, 2, 3];
assert_eq!(a.iter().last(), Some(&3));

let a = [1, 2, 3, 4, 5];
assert_eq!(a.iter().last(), Some(&5));
Run
🔬 This is a nightly-only experimental API. (iter_advance_by #77404)

recently added

通过 n 元素使迭代器前进。

该方法将通过最多 n 次调用 next 来急切地跳过 n 元素,直到遇到 None

advance_by(n) 如果迭代器成功地将 n 元素推进,则返回 Ok(()); 如果遇到 None,则返回 Err(k),其中 k 是迭代器在元素用尽之前被推进的元素数 (即 迭代器的长度)。 请注意,k 始终小于 n

调用 advance_by(0) 不会消耗任何元素,并且始终返回 Ok(())

Examples

基本用法:

#![feature(iter_advance_by)]

let a = [1, 2, 3, 4];
let mut iter = a.iter();

assert_eq!(iter.advance_by(2), Ok(()));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.advance_by(0), Ok(()));
assert_eq!(iter.advance_by(100), Err(1)); // 仅跳过 `&4`
Run

返回迭代器的第 n 个元素。

像大多数索引操作一样,计数从零开始,因此 nth(0) 返回第一个值,nth(1) 返回第二个值,依此类推。

请注意,所有先前的元素以及返回的元素都将从迭代器中使用。 这意味着前面的元素将被丢弃,并且在同一迭代器上多次调用 nth(0) 将返回不同的元素。

nth() 如果 n 大于或等于迭代器的长度,则将返回 None

Examples

基本用法:

let a = [1, 2, 3];
assert_eq!(a.iter().nth(1), Some(&2));
Run

多次调用 nth() 不会回退迭代器:

let a = [1, 2, 3];

let mut iter = a.iter();

assert_eq!(iter.nth(1), Some(&2));
assert_eq!(iter.nth(1), None);
Run

如果少于 n + 1 个元素,则返回 None:

let a = [1, 2, 3];
assert_eq!(a.iter().nth(10), None);
Run

创建一个从同一点开始的迭代器,但在每次迭代时以给定的数量逐步执行。

Note 1: 无论给出的步骤如何,总是会返回迭代器的第一个元素。

Note 2: 被忽略的元素被拉出的时间不是固定的。 StepBy 行为类似于序列 self.next(), self.nth(step-1), self.nth(step-1), …,但也可以像序列 advance_n_and_return_first(&mut self, step), advance_n_and_return_first(&mut self, step), … 一样自由地行为。出于性能原因,某些迭代器使用哪种方式可能会改变。

第二种方法将使迭代器更早地进行,并可能消耗更多的项。

advance_n_and_return_first 等价于:

fn advance_n_and_return_first<I>(iter: &mut I, n: usize) -> Option<I::Item>
where
    I: Iterator,
{
    let next = iter.next();
    if n > 1 {
        iter.nth(n - 2);
    }
    next
}
Run

Panics

如果给定步骤为 0,则该方法将为 panic。

Examples

基本用法:

let a = [0, 1, 2, 3, 4, 5];
let mut iter = a.iter().step_by(2);

assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), None);
Run

接受两个迭代器,并依次在两个迭代器上创建一个新的迭代器。

chain() 将返回一个新的迭代器,该迭代器将首先对第一个迭代器的值进行迭代,然后对第二个迭代器的值进行迭代。

换句话说,它将两个迭代器链接在一起。🔗

once 通常用于将单个值调整为其他类型的迭代链。

Examples

基本用法:

let a1 = [1, 2, 3];
let a2 = [4, 5, 6];

let mut iter = a1.iter().chain(a2.iter());

assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), Some(&5));
assert_eq!(iter.next(), Some(&6));
assert_eq!(iter.next(), None);
Run

由于 chain() 的参数使用 IntoIterator,因此我们可以传递可以转换为 Iterator 的所有内容,而不仅仅是 Iterator 本身。 例如,切片 (&[T]) 实现 IntoIterator,因此可以直接传递给 chain():

let s1 = &[1, 2, 3];
let s2 = &[4, 5, 6];

let mut iter = s1.iter().chain(s2);

assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&4));
assert_eq!(iter.next(), Some(&5));
assert_eq!(iter.next(), Some(&6));
assert_eq!(iter.next(), None);
Run

如果使用 Windows API,则可能希望将 OsStr 转换为 Vec<u16>:

#[cfg(windows)]
fn os_str_to_utf16(s: &std::ffi::OsStr) -> Vec<u16> {
    use std::os::windows::ffi::OsStrExt;
    s.encode_wide().chain(std::iter::once(0)).collect()
}
Run

将两个迭代器压缩为成对的单个迭代器。

zip() 返回一个新的迭代器,该迭代器将在其他两个迭代器上进行迭代,返回一个元组,其中第一个元素来自第一个迭代器,第二个元素来自第二个迭代器。

换句话说,它将两个迭代器压缩在一起,形成一个单一的迭代器。

如果任一迭代器返回 None,则 zipped 迭代器中的 next 将返回 None。 如果第一个迭代器返回 None,则 zip 将短路,第二个迭代器将不会调用 next

Examples

基本用法:

let a1 = [1, 2, 3];
let a2 = [4, 5, 6];

let mut iter = a1.iter().zip(a2.iter());

assert_eq!(iter.next(), Some((&1, &4)));
assert_eq!(iter.next(), Some((&2, &5)));
assert_eq!(iter.next(), Some((&3, &6)));
assert_eq!(iter.next(), None);
Run

由于 zip() 的参数使用 IntoIterator,因此我们可以传递可以转换为 Iterator 的所有内容,而不仅仅是 Iterator 本身。 例如,切片 (&[T]) 实现 IntoIterator,因此可以直接传递给 zip():

let s1 = &[1, 2, 3];
let s2 = &[4, 5, 6];

let mut iter = s1.iter().zip(s2);

assert_eq!(iter.next(), Some((&1, &4)));
assert_eq!(iter.next(), Some((&2, &5)));
assert_eq!(iter.next(), Some((&3, &6)));
assert_eq!(iter.next(), None);
Run

zip() 通常用于将无限迭代器压缩为有限迭代器。 这是可行的,因为有限迭代器最终将返回 None,从而结束拉链。使用 (0..) 压缩看起来很像 enumerate:

let enumerate: Vec<_> = "foo".chars().enumerate().collect();

let zipper: Vec<_> = (0..).zip("foo".chars()).collect();

assert_eq!((0, 'f'), enumerate[0]);
assert_eq!((0, 'f'), zipper[0]);

assert_eq!((1, 'o'), enumerate[1]);
assert_eq!((1, 'o'), zipper[1]);

assert_eq!((2, 'o'), enumerate[2]);
assert_eq!((2, 'o'), zipper[2]);
Run
🔬 This is a nightly-only experimental API. (iter_intersperse #79524)

recently added

创建一个新的迭代器,该迭代器将 separator 的副本放置在原始迭代器的相邻项之间。

如果 separator 未实现 Clone 或每次都需要计算,请使用 intersperse_with

Examples

基本用法:

#![feature(iter_intersperse)]

let mut a = [0, 1, 2].iter().intersperse(&100);
assert_eq!(a.next(), Some(&0));   // `a` 中的第一个元素。
assert_eq!(a.next(), Some(&100)); // 分隔符。
assert_eq!(a.next(), Some(&1));   // `a` 中的下一个元素。
assert_eq!(a.next(), Some(&100)); // 分隔符。
assert_eq!(a.next(), Some(&2));   // `a` 中的最后一个元素。
assert_eq!(a.next(), None);       // 迭代器完成。
Run

intersperse 使用公共元素来加入迭代器的项可能非常有用:

#![feature(iter_intersperse)]

let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
assert_eq!(hello, "Hello World !");
Run
🔬 This is a nightly-only experimental API. (iter_intersperse #79524)

recently added

创建一个新的迭代器,该迭代器将 separator 生成的项放在原始迭代器的相邻项之间。

每次将一个项放置在底层迭代器的两个相邻项之间时,闭包将被精确地调用一次; 具体来说,如果基础迭代器的产量少于两个项目,并且在产生最后一个项目之后,则不调用闭包。

如果迭代器的项实现 Clone,则使用 intersperse 可能会更容易。

Examples

基本用法:

#![feature(iter_intersperse)]

#[derive(PartialEq, Debug)]
struct NotClone(usize);

let v = vec![NotClone(0), NotClone(1), NotClone(2)];
let mut it = v.into_iter().intersperse_with(|| NotClone(99));

assert_eq!(it.next(), Some(NotClone(0)));  // `v` 中的第一个元素。
assert_eq!(it.next(), Some(NotClone(99))); // 分隔符。
assert_eq!(it.next(), Some(NotClone(1)));  // `v` 中的下一个元素。
assert_eq!(it.next(), Some(NotClone(99))); // 分隔符。
assert_eq!(it.next(), Some(NotClone(2)));  // 来自 `v` 的最后一个元素。
assert_eq!(it.next(), None);               // 迭代器完成。
Run

intersperse_with 可以在需要计算分隔符的情况下使用:

#![feature(iter_intersperse)]

let src = ["Hello", "to", "all", "people", "!!"].iter().copied();

// 闭包可变地借用其上下文以生成项。
let mut happy_emojis = [" ❤️ ", " 😀 "].iter().copied();
let separator = || happy_emojis.next().unwrap_or(" 🦀 ");

let result = src.intersperse_with(separator).collect::<String>();
assert_eq!(result, "Hello ❤️ to 😀 all 🦀 people 🦀 !!");
Run

获取一个闭包并创建一个迭代器,该迭代器在每个元素上调用该闭包。

map() 通过其参数将一个迭代器转换为另一个迭代器: 实现 FnMut 的东西。它产生一个新的迭代器,在原始迭代器的每个元素上调用此闭包。

如果您善于思考类型,则可以这样考虑 map(): 如果您有一个迭代器为您提供某种类型的 A 元素,并且您想要某种其他类型的 B 的迭代器,则可以使用 map(),传递一个需要 A 并返回 B 的闭包。

map() 从概念上讲,它类似于 for 循环。但是,由于 map() 是惰性的,因此当您已经在使用其他迭代器时,最好使用 map()。 如果您要进行某种循环的副作用,则认为使用 for 比使用 map() 更惯用。

Examples

基本用法:

let a = [1, 2, 3];

let mut iter = a.iter().map(|x| 2 * x);

assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), Some(6));
assert_eq!(iter.next(), None);
Run

如果您正在做某种副作用,请首选 for 而不是 map():

// 不要这样做:
(0..5).map(|x| println!("{}", x));

// 它甚至不会执行,因为它很懒。Rust 会就此警告您。

// 而是用于:
for x in 0..5 {
    println!("{}", x);
}
Run

在迭代器的每个元素上调用一个闭包。

这等效于在迭代器上使用 for 循环,尽管不能从封闭包中获得 breakcontinue。 通常,使用 for 循环更为习惯,但是在较长的迭代器链的末尾处理 Item 时,for_each 可能更容易理解。

在某些情况下,for_each 可能比循环还要快,因为它会在 Chain 之类的适配器上使用内部迭代。

Examples

基本用法:

use std::sync::mpsc::channel;

let (tx, rx) = channel();
(0..5).map(|x| x * 2 + 1)
      .for_each(move |x| tx.send(x).unwrap());

let v: Vec<_> =  rx.iter().collect();
assert_eq!(v, vec![1, 3, 5, 7, 9]);
Run

对于这么小的示例,for 循环可能更干净,但是 for_each 可能更适合于保留具有较长迭代器的功能样式:

(0..5).flat_map(|x| x * 100 .. x * 110)
      .enumerate()
      .filter(|&(i, x)| (i + x) % 3 == 0)
      .for_each(|(i, x)| println!("{}:{}", i, x));
Run

创建一个迭代器,该迭代器使用闭包确定是否应产生元素。

给定一个元素,闭包必须返回 truefalse。返回的迭代器将仅生成闭包为其返回 true 的元素。

Examples

基本用法:

let a = [0i32, 1, 2];

let mut iter = a.iter().filter(|x| x.is_positive());

assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
Run

因为传递给 filter() 的闭包需要用一个引号引起来,并且许多迭代器迭代引用,所以这可能导致混乱的情况,其中闭包的类型是双引号:

let a = [0, 1, 2];

let mut iter = a.iter().filter(|x| **x > 1); // 需要两个 *s!

assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
Run

通常在参数上使用解构来去掉一个:

let a = [0, 1, 2];

let mut iter = a.iter().filter(|&x| *x > 1); // & 和 *

assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
Run

或两个:

let a = [0, 1, 2];

let mut iter = a.iter().filter(|&&x| x > 1); // 两个 &s

assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
Run

这些层。

请注意,iter.filter(f).next() 等效于 iter.find(f)

创建一个同时过滤和 maps 的迭代器。

返回的迭代器只产生 value,而提供的闭包会返回 Some(value)

filter_map 可用于使 filtermap 的链更简洁。 下面的示例显示了如何将 map().filter().map() 缩短为 filter_map 的单个调用。

Examples

基本用法:

let a = ["1", "two", "NaN", "four", "5"];

let mut iter = a.iter().filter_map(|s| s.parse().ok());

assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
Run

这是相同的示例,但使用 filtermap:

let a = ["1", "two", "NaN", "four", "5"];
let mut iter = a.iter().map(|s| s.parse()).filter(|s| s.is_ok()).map(|s| s.unwrap());
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
Run

创建一个迭代器,该迭代器给出当前迭代次数以及下一个值。

返回的迭代器产生对 (i, val),其中 i 是当前迭代索引,val 是迭代器返回的值。

enumerate() 保持其计数为 usize。 如果要使用其他大小的整数进行计数,则 zip 函数提供了类似的功能。

溢出行为

该方法无法防止溢出,因此枚举多个 usize::MAX 元素会产生错误的结果或 panics。 如果启用了调试断言,则将保证 panic。

Panics

如果要返回的索引将溢出 usize,则返回的迭代器可能为 panic。

Examples

let a = ['a', 'b', 'c'];

let mut iter = a.iter().enumerate();

assert_eq!(iter.next(), Some((0, &'a')));
assert_eq!(iter.next(), Some((1, &'b')));
assert_eq!(iter.next(), Some((2, &'c')));
assert_eq!(iter.next(), None);
Run

创建一个迭代器,它可以使用 peekpeek_mut 方法查看迭代器的下一个元素而不消耗它。有关更多信息,请参见他们的文档。

注意,第一次调用 peekpeek_mut 时,底层迭代器仍然在前进: 为了检索下一个元素,在底层迭代器上调用 next,因此会产生任何副作用 (即 除了获取 next 方法的下一个值之外,其他所有操作都将发生。

Examples

基本用法:

let xs = [1, 2, 3];

let mut iter = xs.iter().peekable();

// peek() 让我们看看 future
assert_eq!(iter.peek(), Some(&&1));
assert_eq!(iter.next(), Some(&1));

assert_eq!(iter.next(), Some(&2));

// 我们可以多次 peek(),迭代器不会前进
assert_eq!(iter.peek(), Some(&&3));
assert_eq!(iter.peek(), Some(&&3));

assert_eq!(iter.next(), Some(&3));

// 迭代器完成后,peek() 也是如此
assert_eq!(iter.peek(), None);
assert_eq!(iter.next(), None);
Run

使用 peek_mut 在不推进迭代器的情况下改变下一个项:

let xs = [1, 2, 3];

let mut iter = xs.iter().peekable();

// `peek_mut()` 让我们看看 future
assert_eq!(iter.peek_mut(), Some(&mut &1));
assert_eq!(iter.peek_mut(), Some(&mut &1));
assert_eq!(iter.next(), Some(&1));

if let Some(mut p) = iter.peek_mut() {
    assert_eq!(*p, &2);
    // 将一个值放入迭代器
    *p = &1000;
}

// 随着迭代器的继续,该值重新出现
assert_eq!(iter.collect::<Vec<_>>(), vec![&1000, &3]);
Run

创建一个迭代器,该迭代器基于谓词 skip 个元素。

skip_while() 将闭包作为参数。它将在迭代器的每个元素上调用此闭包,并忽略元素,直到返回 false

返回 false 后,skip_while () 的工作结束,并产生元素的剩余部分。

Examples

基本用法:

let a = [-1i32, 0, 1];

let mut iter = a.iter().skip_while(|x| x.is_negative());

assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), None);
Run

因为传递给 skip_while() 的闭包需要一个引号,并且许多迭代器都在引用上进行迭代,所以这会导致一种可能令人困惑的情况,其中闭包参数的类型是双引号:

let a = [-1, 0, 1];

let mut iter = a.iter().skip_while(|x| **x < 0); // 需要两个 *s!

assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), None);
Run

在初始 false 之后停止:

let a = [-1, 0, 1, -2];

let mut iter = a.iter().skip_while(|x| **x < 0);

assert_eq!(iter.next(), Some(&0));
assert_eq!(iter.next(), Some(&1));

// 虽然这本来是错误的,但是由于我们已经得到了错误,所以不再使用 skip_while()
assert_eq!(iter.next(), Some(&-2));

assert_eq!(iter.next(), None);
Run

创建一个迭代器,该迭代器根据谓词产生元素。

take_while() 将闭包作为参数。它将在迭代器的每个元素上调用此闭包,并在返回 true 时产生 yield 元素。

返回 false 后,take_while () 的工作结束,并且元素的剩余部分被忽略。

Examples

基本用法:

let a = [-1i32, 0, 1];

let mut iter = a.iter().take_while(|x| x.is_negative());

assert_eq!(iter.next(), Some(&-1));
assert_eq!(iter.next(), None);
Run

因为传递给 take_while() 的闭包需要用一个引号引起来,并且许多迭代器迭代引用,所以这可能导致混乱的情况,其中闭包的类型是双引号:

let a = [-1, 0, 1];

let mut iter = a.iter().take_while(|x| **x < 0); // 需要两个 *s!

assert_eq!(iter.next(), Some(&-1));
assert_eq!(iter.next(), None);
Run

在初始 false 之后停止:

let a = [-1, 0, 1, -2];

let mut iter = a.iter().take_while(|x| **x < 0);

assert_eq!(iter.next(), Some(&-1));

// 我们有更多小于零的元素,但是由于我们已经得到了错误,因此不再使用 take_while()
assert_eq!(iter.next(), None);
Run

因为 take_while() 需要查看该值以查看是否应包含它,所以使用迭代器的人将看到它已被删除:

let a = [1, 2, 3, 4];
let mut iter = a.iter();

let result: Vec<i32> = iter.by_ref()
                           .take_while(|n| **n != 3)
                           .cloned()
                           .collect();

assert_eq!(result, &[1, 2]);

let result: Vec<i32> = iter.cloned().collect();

assert_eq!(result, &[4]);
Run

3 不再存在,因为它已被消耗以查看迭代是否应该停止,但并未放回到迭代器中。

🔬 This is a nightly-only experimental API. (iter_map_while #68537)

recently added

创建一个迭代器,该迭代器均基于谓词和 maps 产生元素。

map_while() 将闭包作为参数。 它将在迭代器的每个元素上调用此闭包,并在返回 Some(_) 时产生 yield 元素。

Examples

基本用法:

#![feature(iter_map_while)]
let a = [-1i32, 4, 0, 1];

let mut iter = a.iter().map_while(|x| 16i32.checked_div(*x));

assert_eq!(iter.next(), Some(-16));
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), None);
Run

这是相同的示例,但使用 take_whilemap:

let a = [-1i32, 4, 0, 1];

let mut iter = a.iter()
                .map(|x| 16i32.checked_div(*x))
                .take_while(|x| x.is_some())
                .map(|x| x.unwrap());

assert_eq!(iter.next(), Some(-16));
assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), None);
Run

在初始 None 之后停止:

#![feature(iter_map_while)]
use std::convert::TryFrom;

let a = [0, 1, 2, -3, 4, 5, -6];

let iter = a.iter().map_while(|x| u32::try_from(*x).ok());
let vec = iter.collect::<Vec<_>>();

// 我们还有更多可能适合 u32 (4,5) 的元素,但是 `map_while` 为 `-3` 返回了 `None` (因为 `predicate` 返回了 `None`),而 `collect` 在遇到的第一个 `None` 处停止。
assert_eq!(vec, vec![0, 1, 2]);
Run

因为 map_while() 需要查看该值以查看是否应包含它,所以使用迭代器的人将看到它已被删除:

#![feature(iter_map_while)]
use std::convert::TryFrom;

let a = [1, 2, -3, 4];
let mut iter = a.iter();

let result: Vec<u32> = iter.by_ref()
                           .map_while(|n| u32::try_from(*n).ok())
                           .collect();

assert_eq!(result, &[1, 2]);

let result: Vec<i32> = iter.cloned().collect();

assert_eq!(result, &[4]);
Run

-3 不再存在,因为它已被消耗以查看迭代是否应该停止,但并未放回到迭代器中。

请注意,与 take_while 不同,此迭代器是不融合的。 还没有指定返回第一个 None 之后此迭代器返回的内容。 如果需要融合迭代器,请使用 fuse

创建一个跳过前 n 个元素的迭代器。

skip(n) 跳过元素,直到跳过 n 个元素或到达迭代器的末尾 (以先发生者为准)。之后,产生所有剩余的元素。

特别是,如果原始迭代器太短,则返回的迭代器为空。

而不是直接覆盖此方法,而是覆盖 nth 方法。

Examples

基本用法:

let a = [1, 2, 3];

let mut iter = a.iter().skip(2);

assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), None);
Run

创建一个迭代器,它产生第一个 n 元素,如果底层迭代器提前结束,则产生更少的元素。

take(n) 产生元素直到 n 元素被产生或到达迭代器的末尾 (以先发生的为准)。 如果原始迭代器包含至少 n 个元素,则返回的迭代器是一个长度为 n 的前缀,否则它包含原始迭代器的所有 (少于 n) 个元素。

Examples

基本用法:

let a = [1, 2, 3];

let mut iter = a.iter().take(2);

assert_eq!(iter.next(), Some(&1));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), None);
Run

take() 通常与无限迭代器配合使用以使其变得有限:

let mut iter = (0..).take(3);

assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
Run

如果少于 n 个元素可用,则 take 会将其自身限制为基础迭代器的大小:

let v = vec![1, 2];
let mut iter = v.into_iter().take(5);
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);
Run

fold 相似的迭代器适配器,它保持内部状态并生成新的迭代器。

scan() 接受两个参数: 一个初始值,该初始值填充内部状态; 一个闭包,包含两个参数,第一个是对内部状态的变量引用,第二个是迭代器元素。

闭包可以分配给内部状态,以在迭代之间共享状态。

迭代时,闭包将应用于迭代器的每个元素,并且闭包的返回值 Option 由迭代器产生。

Examples

基本用法:

let a = [1, 2, 3];

let mut iter = a.iter().scan(1, |state, &x| {
    // 每次迭代,我们将状态乘以元素
    *state = *state * x;

    // 然后,我们将得出国家的否定
    Some(-*state)
});

assert_eq!(iter.next(), Some(-1));
assert_eq!(iter.next(), Some(-2));
assert_eq!(iter.next(), Some(-6));
assert_eq!(iter.next(), None);
Run

创建一个迭代器,其工作方式类似于 map,但是将嵌套的结构展平。

map 适配器非常有用,但仅当闭包参数产生值时才使用。 如果它产生一个迭代器,则存在一个额外的间接层。 flat_map() 会自行删除此额外的图层。

您可以把 flat_map(f) 视为 map 的语义等价物,然后把 flatten 看作是 map(f).flatten()

关于 flat_map() 的另一种方式: map 的闭包为每个元素返回一个项,而 flat_map () 的闭包为每个元素返回一个迭代器。

Examples

基本用法:

let words = ["alpha", "beta", "gamma"];

// chars() 返回一个迭代器
let merged: String = words.iter()
                          .flat_map(|s| s.chars())
                          .collect();
assert_eq!(merged, "alphabetagamma");
Run

创建一个可简化嵌套结构体的迭代器。

当您具有迭代器的迭代器或可以转换为迭代器的事物的迭代器并且要删除一个间接级别时,此功能很有用。

Examples

基本用法:

let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
let flattened = data.into_iter().flatten().collect::<Vec<u8>>();
assert_eq!(flattened, &[1, 2, 3, 4, 5, 6]);
Run

映射然后展平:

let words = ["alpha", "beta", "gamma"];

// chars() 返回一个迭代器
let merged: String = words.iter()
                          .map(|s| s.chars())
                          .flatten()
                          .collect();
assert_eq!(merged, "alphabetagamma");
Run

您也可以用 flat_map() 来重写它,在这种情况下最好使用 flat_map(),因为它可以更清楚地传达意图:

let words = ["alpha", "beta", "gamma"];

// chars() 返回一个迭代器
let merged: String = words.iter()
                          .flat_map(|s| s.chars())
                          .collect();
assert_eq!(merged, "alphabetagamma");
Run

展平一次只能删除一层嵌套:

let d3 = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]];

let d2 = d3.iter().flatten().collect::<Vec<_>>();
assert_eq!(d2, [&[1, 2], &[3, 4], &[5, 6], &[7, 8]]);

let d1 = d3.iter().flatten().flatten().collect::<Vec<_>>();
assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]);
Run

在这里,我们看到 flatten() 不执行深度展平。 相反,仅删除了一层嵌套。也就是说,如果您用 flatten() 三维数组,则结果将是二维而不是一维的。 要获得一维结构体,您必须再次 flatten()

创建一个迭代器,该迭代器在第一个 None 之后结束。

迭代器返回 None 之后,future 调用可能会或可能不会再次产生 Some(T)fuse() 调整迭代器,以确保在给出 None 之后,它将始终永远返回 None

请注意,Fuse 包装器对实现 FusedIterator trait 的迭代器是无操作的。 fuse() 因此,如果 FusedIterator trait 实现不当,则可能会出现错误行为。

Examples

基本用法:

// 一个在 Some 和 None 之间交替的迭代器
struct Alternate {
    state: i32,
}

impl Iterator for Alternate {
    type Item = i32;

    fn next(&mut self) -> Option<i32> {
        let val = self.state;
        self.state = self.state + 1;

        // 如果是偶数,则为 Some(i32),否则为 None
        if val % 2 == 0 {
            Some(val)
        } else {
            None
        }
    }
}

let mut iter = Alternate { state: 0 };

// 我们可以看到我们的迭代器来回走动
assert_eq!(iter.next(), Some(0));
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), Some(2));
assert_eq!(iter.next(), None);

// 但是,一旦我们融合了...
let mut iter = iter.fuse();

assert_eq!(iter.next(), Some(4));
assert_eq!(iter.next(), None);

// 第一次之后它将始终返回 `None`。
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
assert_eq!(iter.next(), None);
Run

对迭代器的每个元素执行某些操作,将值传递给它。

使用迭代器时,通常会将其中的几个链接在一起。 在处理此类代码时,您可能想要切换到管道中各个部分的情况。为此,将一个调用插入 inspect()

inspect() 用作调试工具要比最终代码中存在的更为普遍,但是在某些情况下,如果需要先记录错误然后丢弃,应用程序可能会发现它很有用。

Examples

基本用法:

let a = [1, 4, 2, 3];

// 该迭代器序列很复杂。
let sum = a.iter()
    .cloned()
    .filter(|x| x % 2 == 0)
    .fold(0, |sum, i| sum + i);

println!("{}", sum);

// 让我们添加一些 inspect() 调用以调查正在发生的事情
let sum = a.iter()
    .cloned()
    .inspect(|x| println!("about to filter: {}", x))
    .filter(|x| x % 2 == 0)
    .inspect(|x| println!("made it through filter: {}", x))
    .fold(0, |sum, i| sum + i);

println!("{}", sum);
Run

这将打印:

6
about to filter: 1
about to filter: 4
made it through filter: 4
about to filter: 2
made it through filter: 2
about to filter: 3
6

在丢弃错误之前记录错误:

let lines = ["1", "2", "a"];

let sum: i32 = lines
    .iter()
    .map(|line| line.parse::<i32>())
    .inspect(|num| {
        if let Err(ref e) = *num {
            println!("Parsing error: {}", e);
        }
    })
    .filter_map(Result::ok)
    .sum();

println!("Sum: {}", sum);
Run

这将打印:

Parsing error: invalid digit found in string
Sum: 3

借用一个迭代器,而不是使用它。

这在允许应用迭代器适配器的同时仍保留原始迭代器的所有权很有用。

Examples

基本用法:

let mut words = vec!["hello", "world", "of", "Rust"].into_iter();

// 以前两个单词为例。
let hello_world: Vec<_> = words.by_ref().take(2).collect();
assert_eq!(hello_world, vec!["hello", "world"]);

// 收集剩下的单词。
// 我们只能这样做,因为我们之前使用了 `by_ref`。
let of_rust: Vec<_> = words.collect();
assert_eq!(of_rust, vec!["of", "Rust"]);
Run

将迭代器转换为集合。

collect() 可以采取任何可迭代的方法,并将其转化为相关的集合。 这是在各种上下文中使用的标准库中功能更强大的方法之一。

使用 collect() 的最基本模式是将一个集合转换为另一个集合。 您进行了一个收集,在其上调用 iter,进行了一堆转换,最后添加 collect()

collect() 也可以创建非典型集合类型的实例。 例如,可以从 char 构建一个 String,并且可以将 Result<T, E> 项的迭代器收集到 Result<Collection<T>, E> 中。

有关更多信息,请参见下面的示例。

由于 collect() 非常通用,因此可能导致类型推断问题。 因此,collect() 是为数不多的被亲切地称为 ‘turbofish’ 的语法之一: ::<>. 这有助于推理算法特别了解您要收集到的集合。

Examples

基本用法:

let a = [1, 2, 3];

let doubled: Vec<i32> = a.iter()
                         .map(|&x| x * 2)
                         .collect();

assert_eq!(vec![2, 4, 6], doubled);
Run

请注意,我们需要在左侧使用 : Vec<i32>。这是因为我们可以代替收集到例如 VecDeque<T> 中:

use std::collections::VecDeque;

let a = [1, 2, 3];

let doubled: VecDeque<i32> = a.iter().map(|&x| x * 2).collect();

assert_eq!(2, doubled[0]);
assert_eq!(4, doubled[1]);
assert_eq!(6, doubled[2]);
Run

使用 ‘turbofish’ 而不是注解 doubled:

let a = [1, 2, 3];

let doubled = a.iter().map(|x| x * 2).collect::<Vec<i32>>();

assert_eq!(vec![2, 4, 6], doubled);
Run

因为 collect() 只关心您要收集的内容,所以您仍然可以将局部类型提示 _ 与 turbfish 一起使用:

let a = [1, 2, 3];

let doubled = a.iter().map(|x| x * 2).collect::<Vec<_>>();

assert_eq!(vec![2, 4, 6], doubled);
Run

使用 collect() 生成 String:

let chars = ['g', 'd', 'k', 'k', 'n'];

let hello: String = chars.iter()
    .map(|&x| x as u8)
    .map(|x| (x + 1) as char)
    .collect();

assert_eq!("hello", hello);
Run

如果您有 Result<T, E>,您可以使用 collect() 来查看它们是否失败:

let results = [Ok(1), Err("nope"), Ok(3), Err("bad")];

let result: Result<Vec<_>, &str> = results.iter().cloned().collect();

// 给我们第一个错误
assert_eq!(Err("nope"), result);

let results = [Ok(1), Ok(3)];

let result: Result<Vec<_>, &str> = results.iter().cloned().collect();

// 给我们答案列表
assert_eq!(Ok(vec![1, 3]), result);
Run

使用一个迭代器,从中创建两个集合。

传递给 partition() 的谓词可以返回 truefalsepartition() 返回一对,返回的所有元素都为 true,返回的所有元素都为 false

另请参见 is_partitioned()partition_in_place()

Examples

基本用法:

let a = [1, 2, 3];

let (even, odd): (Vec<i32>, Vec<i32>) = a
    .iter()
    .partition(|&n| n % 2 == 0);

assert_eq!(even, vec![2]);
assert_eq!(odd, vec![1, 3]);
Run
🔬 This is a nightly-only experimental API. (iter_partition_in_place #62543)

new API

根据给定的谓词,对迭代器的元素进行就地重新排序,以使所有返回 true 的元素都在所有返回 false 的元素之前。 返回找到的 true 元素的数量。

未维护分区项的相对顺序。

当前实现

当前的算法尝试找到谓词评估为 false 的第一个元素,以及它评估为 true 的最后一个元素,并反复交换它们。

时间复杂度: O(N)

另请参见 is_partitioned()partition()

Examples

#![feature(iter_partition_in_place)]

let mut a = [1, 2, 3, 4, 5, 6, 7];

// 在偶数和赔率之间进行适当的分区
let i = a.iter_mut().partition_in_place(|&n| n % 2 == 0);

assert_eq!(i, 3);
assert!(a[..i].iter().all(|&n| n % 2 == 0)); // evens
assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds
Run
🔬 This is a nightly-only experimental API. (iter_is_partitioned #62544)

new API

检查此迭代器的元素是否根据给定的谓词进行了分区,以便所有返回 true 的元素都在所有返回 false 的元素之前。

另请参见 partition()partition_in_place()

Examples

#![feature(iter_is_partitioned)]

assert!("Iterator".chars().is_partitioned(char::is_uppercase));
assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase));
Run

一个迭代器方法,它只要成功返回就应用函数,并产生单个最终值。

try_fold() 接受两个参数: 一个初始值和一个带有两个参数的闭包: 一个 ‘accumulator’ 和一个元素。 闭包要么成功返回并返回累加器在下一次迭代中应具有的值,要么返回失败,返回错误值并立即将错误值传播回调用方 (short-circuiting)。

初始值是累加器在第一次调用时将具有的值。如果对迭代器的每个元素应用闭包成功,try_fold() 返回最终的累加器作为成功。

当您拥有某个集合,并且希望从中产生单个值时,fold 非常有用。

实现者注意

就此而言,其他几种 (forward) 方法都具有默认实现,因此,如果它可以做得比默认 for 循环实现更好,请尝试显式实现此方法。

特别是,请尝试将此 try_fold() 放在组成此迭代器的内部部件上。 如果需要多次调用,则 ? 运算符可能会很方便地将累加器值链接在一起,但是要提防在这些早期返回之前需要保留的所有不变式。 这是一种 &mut self 方法,因此在此处遇到错误后需要重新开始迭代。

Examples

基本用法:

let a = [1, 2, 3];

// 数组所有元素的校验和
let sum = a.iter().try_fold(0i8, |acc, &x| acc.checked_add(x));

assert_eq!(sum, Some(6));
Run

Short-circuiting:

let a = [10, 20, 30, 100, 40, 50];
let mut it = a.iter();

// 加 100 元素时,此总和溢出
let sum = it.try_fold(0i8, |acc, &x| acc.checked_add(x));
assert_eq!(sum, None);

// 由于发生短路,因此其余元素仍可通过迭代器使用。
assert_eq!(it.len(), 2);
assert_eq!(it.next(), Some(&40));
Run

虽然您不能从 闭包 breakcrate::ops::ControlFlow 类型允许类似的想法:

use std::ops::ControlFlow;

let triangular = (1..30).try_fold(0_i8, |prev, x| {
    if let Some(next) = prev.checked_add(x) {
        ControlFlow::Continue(next)
    } else {
        ControlFlow::Break(prev)
    }
});
assert_eq!(triangular, ControlFlow::Break(120));

let triangular = (1..30).try_fold(0_u64, |prev, x| {
    if let Some(next) = prev.checked_add(x) {
        ControlFlow::Continue(next)
    } else {
        ControlFlow::Break(prev)
    }
});
assert_eq!(triangular, ControlFlow::Continue(435));
Run

一个迭代器方法,该方法将一个容易犯错的函数应用于迭代器中的每个项,在第一个错误处停止并返回该错误。

也可以将其视为 for_each() 的错误形式或 try_fold() 的无状态版本。

Examples

use std::fs::rename;
use std::io::{stdout, Write};
use std::path::Path;

let data = ["no_tea.txt", "stale_bread.json", "torrential_rain.png"];

let res = data.iter().try_for_each(|x| writeln!(stdout(), "{}", x));
assert!(res.is_ok());

let mut it = data.iter().cloned();
let res = it.try_for_each(|x| rename(x, Path::new(x).with_extension("old")));
assert!(res.is_err());
// 它短路,因此其余项仍在迭代器中:
assert_eq!(it.next(), Some("stale_bread.json"));
Run

crate::ops::ControlFlow 类型可以与此方法一起用于在正常循环中使用 breakcontinue 的情况:

use std::ops::ControlFlow;

let r = (2..100).try_for_each(|x| {
    if 323 % x == 0 {
        return ControlFlow::Break(x)
    }

    ControlFlow::Continue(())
});
assert_eq!(r, ControlFlow::Break(17));
Run

通过应用操作将每个元素 fold 到一个累加器中,返回最终结果。

fold() 接受两个参数: 一个初始值和一个带有两个参数的闭包: 一个 ‘accumulator’ 和一个元素。 闭包返回累加器在下一次迭代中应具有的值。

初始值是累加器在第一次调用时将具有的值。

在将此闭包应用于迭代器的每个元素之后,fold() 返回累加器。

该操作有时称为 ‘reduce’ 或 ‘inject’。

当您拥有某个集合,并且希望从中产生单个值时,fold 非常有用。

Note: fold() 和遍历整个迭代器的类似方法对于无限迭代器可能不会终止,即使在 traits 上也可以在有限时间内确定结果。

Note: 如果累加器类型和项类型相同,则可以使用 reduce() 将第一个元素用作初始值。

Note: fold()左关联方式组合元素。 对于像 + 这样的关联性,元素组合的顺序并不重要,但对于像 - 这样的非关联性,顺序会影响最终结果。 对于 fold()右关联版本,请参见 DoubleEndedIterator::rfold()

实现者注意

就此而言,其他几种 (forward) 方法都具有默认实现,因此,如果它可以做得比默认 for 循环实现更好,请尝试显式实现此方法。

特别是,请尝试将此 fold() 放在组成此迭代器的内部部件上。

Examples

基本用法:

let a = [1, 2, 3];

// 数组所有元素的总和
let sum = a.iter().fold(0, |acc, x| acc + x);

assert_eq!(sum, 6);
Run

让我们在这里遍历迭代的每个步骤:

elementaccxresult
0
1011
2123
3336

因此,我们的最终结果是 6.

这个例子演示了 fold() 的左关联特性: 它构建一个字符串,从一个初始值开始,从前面到后面的每个元素继续:

let numbers = [1, 2, 3, 4, 5];

let zero = "0".to_string();

let result = numbers.iter().fold(zero, |acc, &x| {
    format!("({} + {})", acc, x)
});

assert_eq!(result, "(((((0 + 1) + 2) + 3) + 4) + 5)");
Run

对于那些不经常使用迭代器的人,通常会使用 for 循环并附带一系列要建立结果的列表。那些可以变成 fold () s:

let numbers = [1, 2, 3, 4, 5];

let mut result = 0;

// for 循环:
for i in &numbers {
    result = result + i;
}

// fold:
let result2 = numbers.iter().fold(0, |acc, &x| acc + x);

// 他们是一样的
assert_eq!(result, result2);
Run

通过重复应用归约运算,将元素缩减为一个。

如果迭代器为空,则返回 None; 否则,返回 None。否则,返回减少的结果。

对于具有至少一个元素的迭代器,这与将迭代器的第一个元素作为初始值的 fold() 相同,将每个后续元素折叠到其中。

Example

找出最大值:

fn find_max<I>(iter: I) -> Option<I::Item>
    where I: Iterator,
          I::Item: Ord,
{
    iter.reduce(|a, b| {
        if a >= b { a } else { b }
    })
}
let a = [10, 20, 5, -23, 0];
let b: [u32; 0] = [];

assert_eq!(find_max(a.iter()), Some(&20));
assert_eq!(find_max(b.iter()), None);
Run

测试迭代器的每个元素是否与谓词匹配。

all() 接受一个返回 truefalse 的闭包。它将这个闭包应用于迭代器的每个元素,如果它们都返回 true,那么 all() 也返回。 如果它们中的任何一个返回 false,则返回 false

all() 短路; 换句话说,它一旦找到 false 就会停止处理,因为无论发生什么,结果也将是 false

空的迭代器将返回 true

Examples

基本用法:

let a = [1, 2, 3];

assert!(a.iter().all(|&x| x > 0));

assert!(!a.iter().all(|&x| x > 2));
Run

在第一个 false 处停止:

let a = [1, 2, 3];

let mut iter = a.iter();

assert!(!iter.all(|&x| x != 2));

// 我们仍然可以使用 `iter`,因为还有更多元素。
assert_eq!(iter.next(), Some(&3));
Run

测试迭代器的任何元素是否与谓词匹配。

any() 接受一个返回 truefalse 的闭包。它将这个闭包应用于迭代器的每个元素,如果它们中的任何一个返回 true,那么 any() 也是如此。 如果它们都返回 false,则返回 false

any() 短路; 换句话说,它一旦找到 true 就会停止处理,因为无论发生什么,结果也将是 true

空的迭代器将返回 false

Examples

基本用法:

let a = [1, 2, 3];

assert!(a.iter().any(|&x| x > 0));

assert!(!a.iter().any(|&x| x > 5));
Run

在第一个 true 处停止:

let a = [1, 2, 3];

let mut iter = a.iter();

assert!(iter.any(|&x| x != 2));

// 我们仍然可以使用 `iter`,因为还有更多元素。
assert_eq!(iter.next(), Some(&2));
Run

搜索满足谓词的迭代器的元素。

find() 接受一个返回 truefalse 的闭包。 它将这个闭包应用于迭代器的每个元素,如果其中任何一个返回 true,则 find() 返回 Some(element)。 如果它们都返回 false,则返回 None

find() 短路; 换句话说,一旦闭包返回 true,它将立即停止处理。

由于 find() 接受 quot,并且许多迭代器迭代 quot,因此导致参数为双 quot 的情况可能令人困惑。

&&x 的以下示例中,您可以看到这种效果。

Examples

基本用法:

let a = [1, 2, 3];

assert_eq!(a.iter().find(|&&x| x == 2), Some(&2));

assert_eq!(a.iter().find(|&&x| x == 5), None);
Run

在第一个 true 处停止:

let a = [1, 2, 3];

let mut iter = a.iter();

assert_eq!(iter.find(|&&x| x == 2), Some(&2));

// 我们仍然可以使用 `iter`,因为还有更多元素。
assert_eq!(iter.next(), Some(&3));
Run

请注意,iter.find(f) 等效于 iter.filter(f).next()

将函数应用于迭代器的元素,并返回第一个非无结果。

iter.find_map(f) 等同于 iter.filter_map(f).next()

Examples

let a = ["lol", "NaN", "2", "5"];

let first_number = a.iter().find_map(|s| s.parse().ok());

assert_eq!(first_number, Some(2));
Run
🔬 This is a nightly-only experimental API. (try_find #63178)

new API

将函数应用于迭代器的元素,并返回第一个真结果或第一个错误。

Examples

#![feature(try_find)]

let a = ["1", "2", "lol", "NaN", "5"];

let is_my_num = |s: &str, search: i32| -> Result<bool, std::num::ParseIntError> {
    Ok(s.parse::<i32>()?  == search)
};

let result = a.iter().try_find(|&&s| is_my_num(s, 2));
assert_eq!(result, Ok(Some(&"2")));

let result = a.iter().try_find(|&&s| is_my_num(s, 5));
assert!(result.is_err());
Run

在迭代器中搜索元素,并返回其索引。

position() 接受一个返回 truefalse 的闭包。 它将这个闭包应用于迭代器的每个元素,如果其中一个返回 true,则 position() 返回 Some(index)。 如果它们全部返回 false,则返回 None

position() 短路; 换句话说,它会在找到 true 后立即停止处理。

溢出行为

该方法无法防止溢出,因此,如果存在多个不匹配的 usize::MAX 元素,则会产生错误的结果或 panics。

如果启用了调试断言,则将保证 panic。

Panics

如果迭代器具有多个 usize::MAX 不匹配元素,则此函数可能为 panic。

Examples

基本用法:

let a = [1, 2, 3];

assert_eq!(a.iter().position(|&x| x == 2), Some(1));

assert_eq!(a.iter().position(|&x| x == 5), None);
Run

在第一个 true 处停止:

let a = [1, 2, 3, 4];

let mut iter = a.iter();

assert_eq!(iter.position(|&x| x >= 2), Some(1));

// 我们仍然可以使用 `iter`,因为还有更多元素。
assert_eq!(iter.next(), Some(&3));

// 返回的索引取决于迭代器状态
assert_eq!(iter.position(|&x| x == 4), Some(0));
Run

从右侧搜索迭代器中的元素,并返回其索引。

rposition() 接受一个返回 truefalse 的闭包。 将从结束开始将此闭包应用于迭代器的每个元素,如果其中一个返回 true,则 rposition() 返回 Some(index)

如果它们全部返回 false,则返回 None

rposition() 短路; 换句话说,它会在找到 true 后立即停止处理。

Examples

基本用法:

let a = [1, 2, 3];

assert_eq!(a.iter().rposition(|&x| x == 3), Some(2));

assert_eq!(a.iter().rposition(|&x| x == 5), None);
Run

在第一个 true 处停止:

let a = [1, 2, 3];

let mut iter = a.iter();

assert_eq!(iter.rposition(|&x| x == 2), Some(1));

// 我们仍然可以使用 `iter`,因为还有更多元素。
assert_eq!(iter.next(), Some(&1));
Run

返回迭代器的最大元素。

如果几个元素最大相等,则返回最后一个元素。如果迭代器为空,则返回 None

请注意,由于 NaN 不可比较,f32/f64 没有实现 Ord。 您可以使用 Iterator::reduce 解决此问题:

assert_eq!(
    vec![2.4, f32::NAN, 1.3]
        .into_iter()
        .reduce(f32::max)
        .unwrap(),
    2.4
);
Run

Examples

基本用法:

let a = [1, 2, 3];
let b: Vec<u32> = Vec::new();

assert_eq!(a.iter().max(), Some(&3));
assert_eq!(b.iter().max(), None);
Run

返回迭代器的最小元素。

如果几个元素相等地最小,则返回第一个元素。 如果迭代器为空,则返回 None

请注意,由于 NaN 不可比较,f32/f64 没有实现 Ord。您可以使用 Iterator::reduce 解决此问题:

assert_eq!(
    vec![2.4, f32::NAN, 1.3]
        .into_iter()
        .reduce(f32::min)
        .unwrap(),
    1.3
);
Run

Examples

基本用法:

let a = [1, 2, 3];
let b: Vec<u32> = Vec::new();

assert_eq!(a.iter().min(), Some(&1));
assert_eq!(b.iter().min(), None);
Run

返回给出指定函数最大值的元素。

如果几个元素最大相等,则返回最后一个元素。 如果迭代器为空,则返回 None

Examples

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10);
Run

返回给出相对于指定比较函数的最大值的元素。

如果几个元素最大相等,则返回最后一个元素。 如果迭代器为空,则返回 None

Examples

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(*a.iter().max_by(|x, y| x.cmp(y)).unwrap(), 5);
Run

返回给出指定函数中最小值的元素。

如果几个元素相等地最小,则返回第一个元素。 如果迭代器为空,则返回 None

Examples

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0);
Run

返回给出相对于指定比较函数的最小值的元素。

如果几个元素相等地最小,则返回第一个元素。 如果迭代器为空,则返回 None

Examples

let a = [-3_i32, 0, 1, 5, -10];
assert_eq!(*a.iter().min_by(|x, y| x.cmp(y)).unwrap(), -10);
Run

反转迭代器的方向。

通常,迭代器从左到右进行迭代。 使用 rev() 之后,迭代器将改为从右向左进行迭代。

仅在迭代器具有结束符的情况下才有可能,因此 rev() 仅适用于 DoubleEndedIterator

Examples

let a = [1, 2, 3];

let mut iter = a.iter().rev();

assert_eq!(iter.next(), Some(&3));
assert_eq!(iter.next(), Some(&2));
assert_eq!(iter.next(), Some(&1));

assert_eq!(iter.next(), None);
Run

将成对的迭代器转换为一对容器。

unzip() 使用整个对的迭代器,产生两个集合: 一个来自对的左侧元素,另一个来自右侧的元素。

从某种意义上说,该函数与 zip 相反。

Examples

基本用法:

let a = [(1, 2), (3, 4)];

let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();

assert_eq!(left, [1, 3]);
assert_eq!(right, [2, 4]);
Run

创建一个迭代器,该迭代器将复制其所有元素。

当在 &T 上具有迭代器,但在 T 上需要迭代器时,此功能很有用。

Examples

基本用法:

let a = [1, 2, 3];

let v_copied: Vec<_> = a.iter().copied().collect();

// 复制的与 .map(|&x| x) 相同
let v_map: Vec<_> = a.iter().map(|&x| x).collect();

assert_eq!(v_copied, vec![1, 2, 3]);
assert_eq!(v_map, vec![1, 2, 3]);
Run

创建一个迭代器,该迭代器将克隆所有元素。

当在 &T 上具有迭代器,但在 T 上需要迭代器时,此功能很有用。

Examples

基本用法:

let a = [1, 2, 3];

let v_cloned: Vec<_> = a.iter().cloned().collect();

// 对于整数,cloneed 与 .map(|&x| x) 相同
let v_map: Vec<_> = a.iter().map(|&x| x).collect();

assert_eq!(v_cloned, vec![1, 2, 3]);
assert_eq!(v_map, vec![1, 2, 3]);
Run

不断重复的迭代器。

迭代器不会在 None 处停止,而是会从头开始重新启动。再次迭代后,它将再次从头开始。然后再次。 然后再次。 Forever.

Examples

基本用法:

let a = [1, 2, 3];

let mut it = a.iter().cycle();

assert_eq!(it.next(), Some(&1));
assert_eq!(it.next(), Some(&2));
assert_eq!(it.next(), Some(&3));
assert_eq!(it.next(), Some(&1));
assert_eq!(it.next(), Some(&2));
assert_eq!(it.next(), Some(&3));
assert_eq!(it.next(), Some(&1));
Run

对迭代器的元素求和。

获取每个元素,将它们添加在一起,然后返回结果。

空的迭代器将返回该类型的零值。

Panics

当调用 sum() 并返回原始整数类型时,如果计算溢出并且启用了调试断言,则此方法将为 panic。

Examples

基本用法:

let a = [1, 2, 3];
let sum: i32 = a.iter().sum();

assert_eq!(sum, 6);
Run

遍历整个迭代器,将所有元素相乘

空的迭代器将返回该类型的一个值。

Panics

当调用 product() 并返回原始整数类型时,如果计算溢出并且启用了调试断言,则方法将为 panic。

Examples

fn factorial(n: u32) -> u32 {
    (1..=n).product()
}
assert_eq!(factorial(0), 1);
assert_eq!(factorial(1), 1);
assert_eq!(factorial(5), 120);
Run

Lexicographically 将此 Iterator 的元素与另一个元素进行比较。

Examples

use std::cmp::Ordering;

assert_eq!([1].iter().cmp([1].iter()), Ordering::Equal);
assert_eq!([1].iter().cmp([1, 2].iter()), Ordering::Less);
assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
Run
🔬 This is a nightly-only experimental API. (iter_order_by #64295)

Lexicographically 就指定的比较函数而言,将此 Iterator 的元素与另一个元素进行比较。

Examples

基本用法:

#![feature(iter_order_by)]

use std::cmp::Ordering;

let xs = [1, 2, 3, 4];
let ys = [1, 4, 9, 16];

assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| x.cmp(&y)), Ordering::Less);
assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal);
assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
Run

Lexicographically 将此 Iterator 的元素与另一个元素进行比较。

Examples

use std::cmp::Ordering;

assert_eq!([1.].iter().partial_cmp([1.].iter()), Some(Ordering::Equal));
assert_eq!([1.].iter().partial_cmp([1., 2.].iter()), Some(Ordering::Less));
assert_eq!([1., 2.].iter().partial_cmp([1.].iter()), Some(Ordering::Greater));

assert_eq!([f64::NAN].iter().partial_cmp([1.].iter()), None);
Run
🔬 This is a nightly-only experimental API. (iter_order_by #64295)

Lexicographically 就指定的比较函数而言,将此 Iterator 的元素与另一个元素进行比较。

Examples

基本用法:

#![feature(iter_order_by)]

use std::cmp::Ordering;

let xs = [1.0, 2.0, 3.0, 4.0];
let ys = [1.0, 4.0, 9.0, 16.0];

assert_eq!(
    xs.iter().partial_cmp_by(&ys, |&x, &y| x.partial_cmp(&y)),
    Some(Ordering::Less)
);
assert_eq!(
    xs.iter().partial_cmp_by(&ys, |&x, &y| (x * x).partial_cmp(&y)),
    Some(Ordering::Equal)
);
assert_eq!(
    xs.iter().partial_cmp_by(&ys, |&x, &y| (2.0 * x).partial_cmp(&y)),
    Some(Ordering::Greater)
);
Run

确定此 Iterator 的元素是否与另一个元素相同。

Examples

assert_eq!([1].iter().eq([1].iter()), true);
assert_eq!([1].iter().eq([1, 2].iter()), false);
Run
🔬 This is a nightly-only experimental API. (iter_order_by #64295)

关于指定的相等函数,确定 Iterator 的元素是否与另一个元素相等。

Examples

基本用法:

#![feature(iter_order_by)]

let xs = [1, 2, 3, 4];
let ys = [1, 4, 9, 16];

assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
Run

确定此 Iterator 的元素是否与另一个元素不相等。

Examples

assert_eq!([1].iter().ne([1].iter()), false);
assert_eq!([1].iter().ne([1, 2].iter()), true);
Run

确定此 Iterator 的元素是否比另一个元素少 按字典顺序

Examples

assert_eq!([1].iter().lt([1].iter()), false);
assert_eq!([1].iter().lt([1, 2].iter()), true);
assert_eq!([1, 2].iter().lt([1].iter()), false);
assert_eq!([1, 2].iter().lt([1, 2].iter()), false);
Run

确定此 Iterator 的元素是否 按字典顺序 小于或等于另一个元素。

Examples

assert_eq!([1].iter().le([1].iter()), true);
assert_eq!([1].iter().le([1, 2].iter()), true);
assert_eq!([1, 2].iter().le([1].iter()), false);
assert_eq!([1, 2].iter().le([1, 2].iter()), true);
Run

确定此 Iterator 的元素是否大于另一个元素的 按字典顺序

Examples

assert_eq!([1].iter().gt([1].iter()), false);
assert_eq!([1].iter().gt([1, 2].iter()), false);
assert_eq!([1, 2].iter().gt([1].iter()), true);
assert_eq!([1, 2].iter().gt([1, 2].iter()), false);
Run

确定此 Iterator 的元素是否 按字典顺序 大于或等于另一个元素。

Examples

assert_eq!([1].iter().ge([1].iter()), true);
assert_eq!([1].iter().ge([1, 2].iter()), false);
assert_eq!([1, 2].iter().ge([1].iter()), true);
assert_eq!([1, 2].iter().ge([1, 2].iter()), true);
Run
🔬 This is a nightly-only experimental API. (is_sorted #53485)

new API

检查此迭代器的元素是否已排序。

也就是说,对于每个元素 a 及其后续元素 ba <= b 必须成立。如果迭代器的结果恰好为零或一个元素,则返回 true

请注意,如果 Self::Item 仅是 PartialOrd,而不是 Ord,则上述定义意味着,如果任何两个连续的项都不具有可比性,则此函数将返回 false

Examples

#![feature(is_sorted)]

assert!([1, 2, 2, 9].iter().is_sorted());
assert!(![1, 3, 2, 4].iter().is_sorted());
assert!([0].iter().is_sorted());
assert!(std::iter::empty::<i32>().is_sorted());
assert!(![0.0, 1.0, f32::NAN].iter().is_sorted());
Run
🔬 This is a nightly-only experimental API. (is_sorted #53485)

new API

检查此迭代器的元素是否使用给定的比较器函数进行排序。

该函数使用给定的 compare 函数来确定两个元素的顺序,而不是使用 PartialOrd::partial_cmp。 除此之外,它等效于 is_sorted。有关更多信息,请参见其文档。

Examples

#![feature(is_sorted)]

assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
assert!(![0.0, 1.0, f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
Run
🔬 This is a nightly-only experimental API. (is_sorted #53485)

new API

检查此迭代器的元素是否使用给定的键提取函数进行排序。

该函数不直接比较迭代器的元素,而是比较元素的键 (由 f 确定)。 除此之外,它等效于 is_sorted。有关更多信息,请参见其文档。

Examples

#![feature(is_sorted)]

assert!(["c", "bb", "aaa"].iter().is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
Run

Implementors

🔬 This is a nightly-only experimental API. (is_sorted #53485)

new API

🔬 This is a nightly-only experimental API. (iter_advance_by #77404)

recently added

🔬 This is a nightly-only experimental API. (iter_advance_by #77404)

recently added

溢出行为

该方法无法防止溢出,因此枚举多个 usize::MAX 元素会产生错误的结果或 panics。 如果启用了调试断言,则将保证 panic。

Panics

如果元素的索引溢出 usize,则可能为 panic。

🔬 This is a nightly-only experimental API. (iter_advance_by #77404)

recently added

🔬 This is a nightly-only experimental API. (iter_advance_by #77404)

recently added