Trait std::iter::Iterator 1.0.0[−][src]
pub trait Iterator {
type Item;
Show 71 methods
fn next(&mut self) -> Option<Self::Item>;
fn size_hint(&self) -> (usize, Option<usize>) { ... }
fn count(self) -> usize { ... }
fn last(self) -> Option<Self::Item> { ... }
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>ⓘ { ... }
fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>ⓘ
where
U: IntoIterator<Item = Self::Item>,
{ ... }
fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>ⓘ
where
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 as Iterator>::Item: Clone, type Item = <I as Iterator>::Item;
where
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 as Iterator>::Item, type Item = <I as Iterator>::Item;
where
G: FnMut() -> Self::Item,
{ ... }
fn map<B, F>(self, f: F) -> Map<Self, F>ⓘ
where
F: FnMut(Self::Item) -> B,
{ ... }
fn for_each<F>(self, f: F)
where
F: FnMut(Self::Item),
{ ... }
fn filter<P>(self, predicate: P) -> Filter<Self, P>ⓘ
where
P: FnMut(&Self::Item) -> bool,
{ ... }
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>ⓘ
where
F: FnMut(Self::Item) -> Option<B>,
{ ... }
fn enumerate(self) -> Enumerate<Self>ⓘ { ... }
fn peekable(self) -> Peekable<Self>ⓘ { ... }
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>ⓘ
where
P: FnMut(&Self::Item) -> bool,
{ ... }
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>ⓘ
where
P: FnMut(&Self::Item) -> bool,
{ ... }
fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>ⓘ
where
P: FnMut(Self::Item) -> Option<B>,
{ ... }
fn skip(self, n: usize) -> Skip<Self>ⓘ { ... }
fn take(self, n: usize) -> Take<Self>ⓘ { ... }
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>ⓘ
where
F: FnMut(&mut St, Self::Item) -> Option<B>,
{ ... }
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>ⓘ
where
U: IntoIterator,
F: FnMut(Self::Item) -> U,
{ ... }
fn flatten(self) -> Flatten<Self>ⓘ
where
Self::Item: IntoIterator,
{ ... }
fn fuse(self) -> Fuse<Self>ⓘ { ... }
fn inspect<F>(self, f: F) -> Inspect<Self, F>ⓘ
where
F: FnMut(&Self::Item),
{ ... }
fn by_ref(&mut self) -> &mut Self { ... }
fn collect<B>(self) -> B
where
B: FromIterator<Self::Item>,
{ ... }
fn partition<B, F>(self, f: F) -> (B, B)
where
B: Default + Extend<Self::Item>,
F: FnMut(&Self::Item) -> bool,
{ ... }
fn partition_in_place<'a, T, P>(self, predicate: P) -> usize
where
T: 'a,
Self: DoubleEndedIterator<Item = &'a mut T>,
P: FnMut(&T) -> bool,
{ ... }
fn is_partitioned<P>(self, predicate: P) -> bool
where
P: FnMut(Self::Item) -> bool,
{ ... }
fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where
F: FnMut(B, Self::Item) -> R,
R: Try<Output = B>,
{ ... }
fn try_for_each<F, R>(&mut self, f: F) -> R
where
F: FnMut(Self::Item) -> R,
R: Try<Output = ()>,
{ ... }
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{ ... }
fn reduce<F>(self, f: F) -> Option<Self::Item>
where
F: FnMut(Self::Item, Self::Item) -> Self::Item,
{ ... }
fn try_reduce<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where
F: FnMut(Self::Item, Self::Item) -> R,
R: Try<Output = Self::Item>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
{ ... }
fn all<F>(&mut self, f: F) -> bool
where
F: FnMut(Self::Item) -> bool,
{ ... }
fn any<F>(&mut self, f: F) -> bool
where
F: FnMut(Self::Item) -> bool,
{ ... }
fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where
P: FnMut(&Self::Item) -> bool,
{ ... }
fn find_map<B, F>(&mut self, f: F) -> Option<B>
where
F: FnMut(Self::Item) -> Option<B>,
{ ... }
fn try_find<F, R>(
&mut self,
f: F
) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where
F: FnMut(&Self::Item) -> R,
R: Try<Output = bool>,
<R as Try>::Residual: Residual<Option<Self::Item>>,
{ ... }
fn position<P>(&mut self, predicate: P) -> Option<usize>
where
P: FnMut(Self::Item) -> bool,
{ ... }
fn rposition<P>(&mut self, predicate: P) -> Option<usize>
where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
{ ... }
fn max(self) -> Option<Self::Item>
where
Self::Item: Ord,
{ ... }
fn min(self) -> Option<Self::Item>
where
Self::Item: Ord,
{ ... }
fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where
B: Ord,
F: FnMut(&Self::Item) -> B,
{ ... }
fn max_by<F>(self, compare: F) -> Option<Self::Item>
where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{ ... }
fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where
B: Ord,
F: FnMut(&Self::Item) -> B,
{ ... }
fn min_by<F>(self, compare: F) -> Option<Self::Item>
where
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
{ ... }
fn rev(self) -> Rev<Self>ⓘ
where
Self: DoubleEndedIterator,
{ ... }
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where
FromA: Default + Extend<A>,
FromB: Default + Extend<B>,
Self: Iterator<Item = (A, B)>,
{ ... }
fn copied<'a, T>(self) -> Copied<Self>ⓘ
where
T: 'a + Copy,
Self: Iterator<Item = &'a T>,
{ ... }
fn cloned<'a, T>(self) -> Cloned<Self>ⓘ
where
T: 'a + Clone,
Self: Iterator<Item = &'a T>,
{ ... }
fn cycle(self) -> Cycle<Self>ⓘ
where
Self: Clone,
{ ... }
fn sum<S>(self) -> S
where
S: Sum<Self::Item>,
{ ... }
fn product<P>(self) -> P
where
P: Product<Self::Item>,
{ ... }
fn cmp<I>(self, other: I) -> Ordering
where
I: IntoIterator<Item = Self::Item>,
Self::Item: Ord,
{ ... }
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
{ ... }
fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
{ ... }
fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
{ ... }
fn eq<I>(self, other: I) -> bool
where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
{ ... }
fn eq_by<I, F>(self, other: I, eq: F) -> bool
where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
{ ... }
fn ne<I>(self, other: I) -> bool
where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
{ ... }
fn lt<I>(self, other: I) -> bool
where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
{ ... }
fn le<I>(self, other: I) -> bool
where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
{ ... }
fn gt<I>(self, other: I) -> bool
where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
{ ... }
fn ge<I>(self, other: I) -> bool
where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
{ ... }
fn is_sorted(self) -> bool
where
Self::Item: PartialOrd<Self::Item>,
{ ... }
fn is_sorted_by<F>(self, compare: F) -> bool
where
F: FnMut(&Self::Item, &Self::Item) -> Option<Ordering>,
{ ... }
fn is_sorted_by_key<F, K>(self, f: F) -> bool
where
F: FnMut(Self::Item) -> K,
K: PartialOrd<K>,
{ ... }
}
Expand description
用于处理迭代器的接口。
这是主要的迭代器 trait。
有关一般迭代器概念的更多信息,请参见 模块级文档。
特别是,您可能想知道如何 实现 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());
RunProvided 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通过 n
元素使迭代器前进。
该方法将通过最多 n
次调用 next
来急切地跳过 n
元素,直到遇到 None
。
如果迭代器成功推进 n
个元素,则 advance_by(n)
将返回 Ok(())
,如果遇到 None
,则返回 Err(k)
,其中 k
是迭代器在用完元素之前推进的元素数 (即
迭代器的长度)。
请注意,k
始终小于 n
。
调用 advance_by(0)
可以做有意义的工作,例如 Flatten
可以推进它的外部迭代器,直到它找到一个不为空的内部迭代器,然后通常允许它返回一个比初始状态更准确的 size_hint()
。
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)
将返回不同的元素。
如果 n
大于或等于迭代器的长度,则 nth()
将返回 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
}
RunPanics
如果给定步骤为 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
。
如果 zipped 迭代器没有更多的元素要返回,那么每次进一步尝试推进它时,将首先尝试最多推进第一个迭代器一次,如果它仍然生成一个项,则尝试最多推进第二个迭代器一次。
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);
Runzip()
通常用于将无限迭代器压缩为有限迭代器。
这是可行的,因为有限迭代器最终将返回 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]);
Runfn intersperse(self, separator: Self::Item) -> Intersperse<Self>ⓘNotable traits for Intersperse<I>impl<I> Iterator for Intersperse<I> where
I: Iterator,
<I as Iterator>::Item: Clone, type Item = <I as Iterator>::Item;
where
Self::Item: Clone,
fn intersperse(self, separator: Self::Item) -> Intersperse<Self>ⓘNotable traits for Intersperse<I>impl<I> Iterator for Intersperse<I> where
I: Iterator,
<I as Iterator>::Item: Clone, type Item = <I as Iterator>::Item;
where
Self::Item: Clone,
impl<I> Iterator for Intersperse<I> where
I: Iterator,
<I as Iterator>::Item: Clone, type Item = <I as Iterator>::Item;
创建一个新的迭代器,该迭代器将 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); // 迭代器完成。
Runintersperse
对于使用公共元素连接迭代器的项非常有用:
#![feature(iter_intersperse)]
let hello = ["Hello", "World", "!"].iter().copied().intersperse(" ").collect::<String>();
assert_eq!(hello, "Hello World !");
Runfn 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 as Iterator>::Item, type Item = <I as Iterator>::Item;
where
G: FnMut() -> Self::Item,
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 as Iterator>::Item, type Item = <I as Iterator>::Item;
where
G: FnMut() -> Self::Item,
impl<I, G> Iterator for IntersperseWith<I, G> where
I: Iterator,
G: FnMut() -> <I as Iterator>::Item, type Item = <I as Iterator>::Item;
创建一个新的迭代器,该迭代器将 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); // 迭代器完成。
Runintersperse_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
循环,尽管不能从封闭包中获得 break
和 continue
。
通常,使用 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创建一个迭代器,该迭代器使用闭包确定是否应产生元素。
给定一个元素,闭包必须返回 true
或 false
。返回的迭代器将仅生成闭包为其返回 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)
。
创建一个同时过滤和映射的迭代器。
返回的迭代器只产生 value
,而提供的闭包会返回 Some(value)
。
filter_map
可用于使 filter
和 map
的链更简洁。
下面的示例显示了如何将 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);
Runlet 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创建一个迭代器,它可以使用 peek
和 peek_mut
方法查看迭代器的下一个元素而不消耗它。有关更多信息,请参见他们的文档。
注意,第一次调用 peek
或 peek_mut
时,底层迭代器仍然在前进:为了检索下一个元素,在底层迭代器上调用 next
,因此会产生任何副作用 (即
除了获取 next
方法的下一个值之外,其他所有操作都将发生。
Examples
基本用法:
let xs = [1, 2, 3];
let mut iter = xs.iter().peekable();
// peek() 让我们能看到未来
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]);
Run3
不再存在,因为它已被消耗以查看迭代是否应该停止,但并未放回到迭代器中。
创建一个迭代器,该迭代器均基于谓词和映射生成元素。
map_while()
将闭包作为参数。
它将在迭代器的每个元素上调用此闭包,并在返回 Some(_)
时产生元素。
Examples
基本用法:
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_while
和 map
:
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
之后停止:
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()
需要查看该值以查看是否应包含它,所以使用迭代器的人将看到它已被删除:
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
元素,如果底层迭代器提前结束,则产生更少的元素。
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);
Runtake()
通常与无限迭代器一起使用,以使其成为有限的:
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");
Run1.29.0[src]fn flatten(self) -> Flatten<Self>ⓘ where
Self::Item: IntoIterator,
fn flatten(self) -> Flatten<Self>ⓘ where
Self::Item: IntoIterator,
创建一个可简化嵌套结构体的迭代器。
当您具有迭代器的迭代器或可以转换为迭代器的事物的迭代器并且要删除一个间接级别时,此功能很有用。
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 的迭代器是无操作的。
因此,如果 FusedIterator
trait 实现不当,fuse()
可能会出现错误行为。
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"]);
Runfn collect<B>(self) -> B where
B: FromIterator<Self::Item>,
fn collect<B>(self) -> B where
B: FromIterator<Self::Item>,
将迭代器转换为集合。
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()
的谓词可以返回 true
或 false
。
partition()
返回一对,它返回 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]);
Runfn partition_in_place<'a, T, P>(self, predicate: P) -> usize where
T: 'a,
Self: DoubleEndedIterator<Item = &'a mut T>,
P: FnMut(&T) -> bool,
fn partition_in_place<'a, T, P>(self, predicate: P) -> usize where
T: 'a,
Self: DoubleEndedIterator<Item = &'a mut T>,
P: FnMut(&T) -> bool,
根据给定的谓词,对迭代器的元素进行就地重新排序,以使所有返回 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检查此迭代器的元素是否根据给定的谓词进行了分区,以便所有返回 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));
RunShort-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虽然您不能从 闭包 break
,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"));
RunControlFlow
类型可以与此方法一起用于在正常循环中使用 break
和 continue
的情况:
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让我们在这里遍历迭代的每个步骤:
element | acc | x | result |
---|---|---|---|
0 | |||
1 | 0 | 1 | 1 |
2 | 1 | 2 | 3 |
3 | 3 | 3 | 6 |
所以,我们的最终结果,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
。否则,返回减少的结果。
Reduce 函数是一个闭包,有两个参数:一个 ‘accumulator’ 和一个元素。
对于具有至少一个元素的迭代器,这与 fold()
相同,将迭代器的第一个元素作为初始累加器值,将每个后续元素 fold 到其中。
Example
找出最大值:
fn find_max<I>(iter: I) -> Option<I::Item>
where I: Iterator,
I::Item: Ord,
{
iter.reduce(|accum, item| {
if accum >= item { accum } else { item }
})
}
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通过重复应用 Reduce 操作,将元素归约为单个元素。 如果闭包返回失败,则失败会立即传播给调用者。
此方法的返回类型取决于闭包的返回类型。
如果闭包返回 Result<Self::Item, E>
,那么这个函数将返回 Result<Option<Self::Item>, E>
。
如果闭包返回 Option<Self::Item>
,那么这个函数将返回 Option<Option<Self::Item>>
。
当调用一个空的迭代器时,这个函数将返回 Some(None)
或 Ok(None)
取决于提供的闭包的类型。
对于至少有一个元素的迭代器,这本质上与使用迭代器的第一个元素作为初始累加器值调用 try_fold()
相同。
Examples
安全地计算一系列数字的总和:
#![feature(iterator_try_reduce)]
let numbers: Vec<usize> = vec![10, 20, 5, 23, 0];
let sum = numbers.into_iter().try_reduce(|x, y| x.checked_add(y));
assert_eq!(sum, Some(Some(58)));
Run确定什么时候 reduction 短路:
#![feature(iterator_try_reduce)]
let numbers = vec![1, 2, 3, usize::MAX, 4, 5];
let sum = numbers.into_iter().try_reduce(|x, y| x.checked_add(y));
assert_eq!(sum, None);
Run确定在什么情况下没有 reduction,因为没有元素:
#![feature(iterator_try_reduce)]
let numbers: Vec<usize> = Vec::new();
let sum = numbers.into_iter().try_reduce(|x, y| x.checked_add(y));
assert_eq!(sum, Some(None));
Run#![feature(iterator_try_reduce)]
let numbers = vec!["1", "2", "3", "4", "5"];
let max: Result<Option<_>, <usize as std::str::FromStr>::Err> =
numbers.into_iter().try_reduce(|x, y| {
if x.parse::<usize>()? > y.parse::<usize>()? { Ok(x) } else { Ok(y) }
});
assert_eq!(max, Ok(Some("5")));
Run测试迭代器的每个元素是否与谓词匹配。
all()
接受一个返回 true
或 false
的闭包。它将这个闭包应用于迭代器的每个元素,如果它们都返回 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()
接受一个返回 true
或 false
的闭包。它将这个闭包应用于迭代器的每个元素,如果它们中的任何一个返回 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()
接受一个返回 true
或 false
的闭包。
它将这个闭包应用于迭代器的每个元素,如果其中任何一个返回 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()
。
将函数应用于迭代器的元素,并返回第一个为 true 的结果或第一个错误。
此方法的返回类型取决于闭包的返回类型。
如果您从闭包中返回 Result<bool, E>
,您会得到一个 Result <Option<Self::Item>; E>
.
如果您从闭包中返回 Option<bool>
,您会得到一个 Option<Option<Self::Item>>
。
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这也支持实现 Try
的其他类型,而不仅仅是 Result
。
#![feature(try_find)]
use std::num::NonZeroU32;
let a = [3, 5, 7, 4, 9, 0, 11];
let result = a.iter().try_find(|&&x| NonZeroU32::new(x).map(|y| y.is_power_of_two()));
assert_eq!(result, Some(Some(&4)));
let result = a.iter().take(3).try_find(|&&x| NonZeroU32::new(x).map(|y| y.is_power_of_two()));
assert_eq!(result, Some(None));
let result = a.iter().rev().try_find(|&&x| NonZeroU32::new(x).map(|y| y.is_power_of_two()));
assert_eq!(result, None);
Run在迭代器中搜索元素,并返回其索引。
position()
接受一个返回 true
或 false
的闭包。
它将这个闭包应用于迭代器的每个元素,如果其中一个返回 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));
Runfn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator,
从右侧搜索迭代器中的元素,并返回其索引。
rposition()
接受一个返回 true
或 false
的闭包。
将从结束开始将此闭包应用于迭代器的每个元素,如果其中一个返回 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
);
RunExamples
基本用法:
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
);
RunExamples
基本用法:
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反转迭代器的方向。
通常,迭代器从左到右进行迭代。
使用 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), (5, 6)];
let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
assert_eq!(left, [1, 3, 5]);
assert_eq!(right, [2, 4, 6]);
// 您还可以一次解压缩多个嵌套元组
let a = [(1, (2, 3)), (4, (5, 6))];
let (x, (y, z)): (Vec<_>, (Vec<_>, Vec<_>)) = a.iter().cloned().unzip();
assert_eq!(x, [1, 4]);
assert_eq!(y, [2, 5]);
assert_eq!(z, [3, 6]);
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));
Runfn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,
字典顺序 根据指定的比较函数将这个 Iterator
的元素与另一个 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);
Run1.5.0[src]fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn partial_cmp<I>(self, other: I) -> Option<Ordering> where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
字典顺序 将这个 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);
Runfn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,
字典顺序 根据指定的比较函数将这个 Iterator
的元素与另一个 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)
);
Run1.5.0[src]fn eq<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
fn eq<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
fn eq_by<I, F>(self, other: I, eq: F) -> bool where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
fn eq_by<I, F>(self, other: I, eq: F) -> bool where
I: IntoIterator,
F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,
1.5.0[src]fn ne<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
fn ne<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialEq<<I as IntoIterator>::Item>,
1.5.0[src]fn lt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn lt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]fn le<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn le<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]fn gt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn gt<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
1.5.0[src]fn ge<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
fn ge<I>(self, other: I) -> bool where
I: IntoIterator,
Self::Item: PartialOrd<<I as IntoIterator>::Item>,
检查此迭代器的元素是否已排序。
也就是说,对于每个元素 a
及其后续元素 b
,a <= 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检查此迭代器的元素是否使用给定的比较器函数进行排序。
该函数使用给定的 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