Trait core::iter::DoubleEndedIterator

1.0.0 · source ·
pub trait DoubleEndedIterator: Iterator {
    // Required method
    fn next_back(&mut self) -> Option<Self::Item>;

    // Provided methods
    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { ... }
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> { ... }
    fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
       where Self: Sized,
             F: FnMut(B, Self::Item) -> R,
             R: Try<Output = B> { ... }
    fn rfold<B, F>(self, init: B, f: F) -> B
       where Self: Sized,
             F: FnMut(B, Self::Item) -> B { ... }
    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
       where Self: Sized,
             P: FnMut(&Self::Item) -> bool { ... }
}
Expand description

一个能够从两端产生元素的迭代器。

实现 DoubleEndedIterator 的东西比实现 Iterator 的东西具有一项额外的功能:既可以从后面也可以从前面获得 item 的功能。

重要的是要注意,来回运动都在相同的范围内,并且不会交叉:当它们在中间相遇时,迭代就结束了。

以与 Iterator 协议类似的方式,一旦 DoubleEndedIteratornext_back() 返回 None,再次调用它可能会也可能不会再返回 Some。 为此,next()next_back() 可以互换。

Examples

基本用法:

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

let mut iter = numbers.iter();

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

Required Methods§

source

fn next_back(&mut self) -> Option<Self::Item>

从迭代器的末尾删除并返回一个元素。

没有更多元素时返回 None

trait-level 文档包含更多详细信息。

Examples

基本用法:

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

let mut iter = numbers.iter();

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

DoubleEndedIterator 方法产生的元素可能与 Iterator 方法产生的元素不同:

let vec = vec![(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b')];
let uniq_by_fst_comp = || {
    let mut seen = std::collections::HashSet::new();
    vec.iter().copied().filter(move |x| seen.insert(x.0))
};

assert_eq!(uniq_by_fst_comp().last(), Some((2, 'a')));
assert_eq!(uniq_by_fst_comp().next_back(), Some((2, 'b')));

assert_eq!(
    uniq_by_fst_comp().fold(vec![], |mut v, x| {v.push(x); v}),
    vec![(1, 'a'), (2, 'a')]
);
assert_eq!(
    uniq_by_fst_comp().rfold(vec![], |mut v, x| {v.push(x); v}),
    vec![(2, 'b'), (1, 'c')]
);
Run

Provided Methods§

source

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>

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

通过 n 元素从后向前推进迭代器。

advance_back_byadvance_by 的反向版本。该方法将急切地从后面开始跳过 n 元素,方法是调用 next_back 最多 n 次,直到遇到 None

如果迭代器成功前进了 n 个元素,advance_back_by(n) 将返回 Ok(()),如果遇到 None,则返回值为 kErr(NonZeroUsize),其中 k 是由于迭代器用完而无法前进的剩余步数。

如果 self 为空且 n 非零,则返回 Err(n)。 否则,k 总是小于 n

调用 advance_back_by(0) 可以做有意义的工作,例如 Flatten 可以推进它的外部迭代器,直到它找到一个不为空的内部迭代器,然后通常允许它返回一个比初始状态更准确的 size_hint()

Examples

基本用法:

#![feature(iter_advance_by)]

use std::num::NonZeroUsize;
let a = [3, 4, 5, 6];
let mut iter = a.iter();

assert_eq!(iter.advance_back_by(2), Ok(()));
assert_eq!(iter.next_back(), Some(&4));
assert_eq!(iter.advance_back_by(0), Ok(()));
assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(99).unwrap())); // 仅跳过 `&3`
Run
1.37.0 · source

fn nth_back(&mut self, n: usize) -> Option<Self::Item>

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

这实际上是 Iterator::nth() 的反向版本。 尽管像大多数索引操作一样,计数从零开始,所以 nth_back(0) 从末尾返回第一个值,nth_back(1) 从第二个开始返回,依此类推。

请注意,将消耗 end 和返回元素之间的所有元素,包括返回元素。 这也意味着在同一迭代器上多次调用 nth_back(0) 将返回不同的元素。

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

Examples

基本用法:

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

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

let a = [1, 2, 3];

let mut iter = a.iter();

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

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

let a = [1, 2, 3];
assert_eq!(a.iter().nth_back(10), None);
Run
1.27.0 · source

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> Rwhere Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Output = B>,

这是 Iterator::try_fold() 的反向版本:它从迭代器的后面开始接收元素。

Examples

基本用法:

let a = ["1", "2", "3"];
let sum = a.iter()
    .map(|&s| s.parse::<i32>())
    .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
assert_eq!(sum, Ok(6));
Run

Short-circuiting:

let a = ["1", "rust", "3"];
let mut it = a.iter();
let sum = it
    .by_ref()
    .map(|&s| s.parse::<i32>())
    .try_rfold(0, |acc, x| x.and_then(|y| Ok(acc + y)));
assert!(sum.is_err());

// 由于发生短路,因此其余元素仍可通过迭代器使用。
assert_eq!(it.next_back(), Some(&"1"));
Run
1.27.0 · source

fn rfold<B, F>(self, init: B, f: F) -> Bwhere Self: Sized, F: FnMut(B, Self::Item) -> B,

一种迭代器方法,从后面开始,将迭代器的元素减少为单个最终值。

这是 Iterator::fold() 的反向版本:它从迭代器的后面开始接收元素。

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

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

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

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

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

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

对于 rfold()左关联版本,请参见 Iterator::fold()

Examples

基本用法:

let a = [1, 2, 3];

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

assert_eq!(sum, 6);
Run

这个例子演示了 rfold() 的右结合性质: 它构建一个字符串,从一个初始值开始,从后面到前面的每个元素继续:

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

let zero = "0".to_string();

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

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

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>where Self: Sized, P: FnMut(&Self::Item) -> bool,

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

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

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

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

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

Examples

基本用法:

let a = [1, 2, 3];

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

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

在第一个 true 处停止:

let a = [1, 2, 3];

let mut iter = a.iter();

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

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

Implementors§

source§

impl DoubleEndedIterator for EscapeDefault

1.59.0 · source§

impl DoubleEndedIterator for ToLowercase

1.59.0 · source§

impl DoubleEndedIterator for ToUppercase

source§

impl DoubleEndedIterator for Bytes<'_>

1.60.0 · source§

impl<'a> DoubleEndedIterator for EscapeAscii<'a>

source§

impl<'a> DoubleEndedIterator for CharIndices<'a>

source§

impl<'a> DoubleEndedIterator for Chars<'a>

source§

impl<'a> DoubleEndedIterator for Lines<'a>

source§

impl<'a> DoubleEndedIterator for LinesAny<'a>

1.34.0 · source§

impl<'a> DoubleEndedIterator for SplitAsciiWhitespace<'a>

1.1.0 · source§

impl<'a> DoubleEndedIterator for SplitWhitespace<'a>

source§

impl<'a, A> DoubleEndedIterator for core::option::Iter<'a, A>

source§

impl<'a, A> DoubleEndedIterator for core::option::IterMut<'a, A>

1.1.0 · source§

impl<'a, I, T> DoubleEndedIterator for Cloned<I>where I: DoubleEndedIterator<Item = &'a T>, T: Clone + 'a,

1.36.0 · source§

impl<'a, I, T> DoubleEndedIterator for Copied<I>where I: DoubleEndedIterator<Item = &'a T>, T: Copy + 'a,

source§

impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I

1.5.0 · source§

impl<'a, P> DoubleEndedIterator for MatchIndices<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

1.2.0 · source§

impl<'a, P> DoubleEndedIterator for Matches<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

1.5.0 · source§

impl<'a, P> DoubleEndedIterator for RMatchIndices<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

1.2.0 · source§

impl<'a, P> DoubleEndedIterator for RMatches<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

source§

impl<'a, P> DoubleEndedIterator for core::str::RSplit<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

source§

impl<'a, P> DoubleEndedIterator for RSplitTerminator<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

source§

impl<'a, P> DoubleEndedIterator for core::str::Split<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

source§

impl<'a, P> DoubleEndedIterator for SplitTerminator<'a, P>where P: Pattern<'a, Searcher: DoubleEndedSearcher<'a>>,

1.51.0 · source§

impl<'a, P: Pattern<'a, Searcher: ReverseSearcher<'a>>> DoubleEndedIterator for core::str::SplitInclusive<'a, P>

source§

impl<'a, T> DoubleEndedIterator for core::result::Iter<'a, T>

source§

impl<'a, T> DoubleEndedIterator for core::result::IterMut<'a, T>

source§

impl<'a, T> DoubleEndedIterator for Chunks<'a, T>

1.31.0 · source§

impl<'a, T> DoubleEndedIterator for ChunksExact<'a, T>

1.31.0 · source§

impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T>

source§

impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T>

source§

impl<'a, T> DoubleEndedIterator for core::slice::Iter<'a, T>

source§

impl<'a, T> DoubleEndedIterator for core::slice::IterMut<'a, T>

1.31.0 · source§

impl<'a, T> DoubleEndedIterator for RChunks<'a, T>

1.31.0 · source§

impl<'a, T> DoubleEndedIterator for RChunksExact<'a, T>

1.31.0 · source§

impl<'a, T> DoubleEndedIterator for RChunksExactMut<'a, T>

1.31.0 · source§

impl<'a, T> DoubleEndedIterator for RChunksMut<'a, T>

source§

impl<'a, T> DoubleEndedIterator for Windows<'a, T>

1.27.0 · source§

impl<'a, T, P> DoubleEndedIterator for core::slice::RSplit<'a, T, P>where P: FnMut(&T) -> bool,

1.27.0 · source§

impl<'a, T, P> DoubleEndedIterator for RSplitMut<'a, T, P>where P: FnMut(&T) -> bool,

source§

impl<'a, T, P> DoubleEndedIterator for core::slice::Split<'a, T, P>where P: FnMut(&T) -> bool,

1.51.0 · source§

impl<'a, T, P> DoubleEndedIterator for core::slice::SplitInclusive<'a, T, P>where P: FnMut(&T) -> bool,

1.51.0 · source§

impl<'a, T, P> DoubleEndedIterator for SplitInclusiveMut<'a, T, P>where P: FnMut(&T) -> bool,

source§

impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P>where P: FnMut(&T) -> bool,

source§

impl<'a, T, const N: usize> DoubleEndedIterator for core::slice::ArrayChunks<'a, T, N>

source§

impl<'a, T, const N: usize> DoubleEndedIterator for ArrayChunksMut<'a, T, N>

source§

impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N>

source§

impl<'a, T: 'a, P> DoubleEndedIterator for GroupBy<'a, T, P>where P: FnMut(&T, &T) -> bool,

source§

impl<'a, T: 'a, P> DoubleEndedIterator for GroupByMut<'a, T, P>where P: FnMut(&T, &T) -> bool,

source§

impl<A> DoubleEndedIterator for core::option::IntoIter<A>

source§

impl<A, B> DoubleEndedIterator for Chain<A, B>where A: DoubleEndedIterator, B: DoubleEndedIterator<Item = A::Item>,

source§

impl<A, B> DoubleEndedIterator for Zip<A, B>where A: DoubleEndedIterator + ExactSizeIterator, B: DoubleEndedIterator + ExactSizeIterator,

1.43.0 · source§

impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F>

source§

impl<A: Clone> DoubleEndedIterator for Repeat<A>

source§

impl<A: Step> DoubleEndedIterator for Range<A>

1.26.0 · source§

impl<A: Step> DoubleEndedIterator for RangeInclusive<A>

source§

impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for FilterMap<I, F>where F: FnMut(I::Item) -> Option<B>,

source§

impl<B, I: DoubleEndedIterator, F> DoubleEndedIterator for Map<I, F>where F: FnMut(I::Item) -> B,

source§

impl<I> DoubleEndedIterator for Enumerate<I>where I: ExactSizeIterator + DoubleEndedIterator,

source§

impl<I> DoubleEndedIterator for Fuse<I>where I: DoubleEndedIterator,

1.38.0 · source§

impl<I> DoubleEndedIterator for Peekable<I>where I: DoubleEndedIterator,

source§

impl<I> DoubleEndedIterator for Rev<I>where I: DoubleEndedIterator,

1.9.0 · source§

impl<I> DoubleEndedIterator for Skip<I>where I: DoubleEndedIterator + ExactSizeIterator,

1.38.0 · source§

impl<I> DoubleEndedIterator for StepBy<I>where I: DoubleEndedIterator + ExactSizeIterator,

1.38.0 · source§

impl<I> DoubleEndedIterator for Take<I>where I: DoubleEndedIterator + ExactSizeIterator,

1.29.0 · source§

impl<I, U> DoubleEndedIterator for Flatten<I>where I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>, U: DoubleEndedIterator,

source§

impl<I, const N: usize> DoubleEndedIterator for core::iter::ArrayChunks<I, N>where I: DoubleEndedIterator + ExactSizeIterator,

source§

impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I>

source§

impl<I: DoubleEndedIterator, F> DoubleEndedIterator for Inspect<I, F>where F: FnMut(&I::Item),

source§

impl<I: DoubleEndedIterator, P> DoubleEndedIterator for Filter<I, P>where P: FnMut(&I::Item) -> bool,

source§

impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>where F: FnMut(I::Item) -> U, U: IntoIterator<IntoIter: DoubleEndedIterator>,

source§

impl<T> DoubleEndedIterator for core::result::IntoIter<T>

1.2.0 · source§

impl<T> DoubleEndedIterator for Empty<T>

1.2.0 · source§

impl<T> DoubleEndedIterator for Once<T>

1.40.0 · source§

impl<T, const N: usize> DoubleEndedIterator for core::array::IntoIter<T, N>