Trait std::iter::FromIterator1.0.0[][src]

pub trait FromIterator<A> {
    fn from_iter<T>(iter: T) -> Self
    where
        T: IntoIterator<Item = A>
; }
Expand description

Iterator 转换。

通过为类型实现 FromIterator,可以定义如何从迭代器创建它。 这对于描述某种集合的类型很常见。

FromIterator::from_iter() 很少显式调用,而是通过 Iterator::collect() 方法使用。

有关更多示例,请参见 [Iterator::collect () ] 的文档。

也可以看看: IntoIterator.

Examples

基本用法:

use std::iter::FromIterator;

let five_fives = std::iter::repeat(5).take(5);

let v = Vec::from_iter(five_fives);

assert_eq!(v, vec![5, 5, 5, 5, 5]);
Run

使用 Iterator::collect() 隐式使用 FromIterator:

let five_fives = std::iter::repeat(5).take(5);

let v: Vec<i32> = five_fives.collect();

assert_eq!(v, vec![5, 5, 5, 5, 5]);
Run

为您的类型实现 FromIterator:

use std::iter::FromIterator;

// 一个样本集合,这只是 Vec<T> 的包装
#[derive(Debug)]
struct MyCollection(Vec<i32>);

// 让我们给它一些方法,以便我们可以创建一个方法并向其中添加一些东西。
impl MyCollection {
    fn new() -> MyCollection {
        MyCollection(Vec::new())
    }

    fn add(&mut self, elem: i32) {
        self.0.push(elem);
    }
}

// 我们将实现 FromIterator
impl FromIterator<i32> for MyCollection {
    fn from_iter<I: IntoIterator<Item=i32>>(iter: I) -> Self {
        let mut c = MyCollection::new();

        for i in iter {
            c.add(i);
        }

        c
    }
}

// 现在我们可以创建一个新的迭代器...
let iter = (0..5).into_iter();

// ... 并用它制作一个 MyCollection
let c = MyCollection::from_iter(iter);

assert_eq!(c.0, vec![0, 1, 2, 3, 4]);

// 也收集作品!

let iter = (0..5).into_iter();
let c: MyCollection = iter.collect();

assert_eq!(c.0, vec![0, 1, 2, 3, 4]);
Run

Required methods

从迭代器创建一个值。

有关更多信息,请参见 module-level documentation

Examples

基本用法:

use std::iter::FromIterator;

let five_fives = std::iter::repeat(5).take(5);

let v = Vec::from_iter(five_fives);

assert_eq!(v, vec![5, 5, 5, 5, 5]);
Run

Implementors

将一个迭代器中的所有 unit 项折叠为一个。

与更高级别的抽象结合使用时,此功能尤其有用,例如收集到仅关心错误的 Result<(), E> 上:

use std::io::*;
let data = vec![1, 2, 3, 4, 5];
let res: Result<()> = data.iter()
    .map(|x| writeln!(stdout(), "{}", x))
    .collect();
assert!(res.is_ok());
Run

接受 Iterator 中的每个元素: 如果它是 Err,则不再获取其他元素,并返回 Err。 如果没有发生 Err,则返回包含每个 Result 值的容器。

这是一个示例,该示例将 vector 中的每个整数递增,并检查溢出:

let v = vec![1, 2];
let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|
    x.checked_add(1).ok_or("Overflow!")
).collect();
assert_eq!(res, Ok(vec![2, 3]));
Run

这是另一个示例,尝试从另一个整数列表中减去一个,这次检查下溢:

let v = vec![1, 2, 0];
let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|
    x.checked_sub(1).ok_or("Underflow!")
).collect();
assert_eq!(res, Err("Underflow!"));
Run

这是前一个示例的变体,显示在第一个 Err 之后不再从 iter 提取其他元素。

let v = vec![3, 2, 1, 10];
let mut shared = 0;
let res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32| {
    shared += x;
    x.checked_sub(2).ok_or("Underflow!")
}).collect();
assert_eq!(res, Err("Underflow!"));
assert_eq!(shared, 6);
Run

由于第三个元素引起下溢,因此不再使用其他元素,因此 shared 的最终值为 6 (= 3 + 2 + 1),而不是 16。

接受 Iterator 中的每个元素: 如果为 None,则不再获取其他元素,并返回 None。 如果没有发生 None,则返回包含每个 Option 值的容器。

Examples

这是一个使 vector 中的每个整数递增的示例。 当计算将导致溢出时,我们使用 add 的检查成员返回 None

let items = vec![0_u16, 1, 2];

let res: Option<Vec<u16>> = items
    .iter()
    .map(|x| x.checked_add(1))
    .collect();

assert_eq!(res, Some(vec![1, 2, 3]));
Run

如您所见,这将返回预期的有效项。

这是另一个示例,尝试从另一个整数列表中减去一个,这次检查下溢:

let items = vec![2_u16, 1, 0];

let res: Option<Vec<u16>> = items
    .iter()
    .map(|x| x.checked_sub(1))
    .collect();

assert_eq!(res, None);
Run

由于最后一个元素为零,因此会下溢。因此,结果值为 None

这是前一个示例的变体,显示在第一个 None 之后不再从 iter 提取其他元素。

let items = vec![3_u16, 2, 1, 10];

let mut shared = 0;

let res: Option<Vec<u16>> = items
    .iter()
    .map(|x| { shared += x; x.checked_sub(2) })
    .collect();

assert_eq!(res, None);
assert_eq!(shared, 6);
Run

由于第三个元素引起下溢,因此不再使用其他元素,因此 shared 的最终值为 6 (= 3 + 2 + 1),而不是 16。

获取 Iterator 中的每个元素,并将其收集到 Rc<[T]> 中。

性能特点

一般情况

在一般情况下,首先要收集到 Vec<T> 中来收集到 Rc<[T]> 中。也就是说,编写以下内容时:

let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
Run

这就像我们写的那样:

let evens: Rc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
    .collect::<Vec<_>>() // 第一组分配在此处发生。
    .into(); // `Rc<[T]>` 的第二个分配在此处进行。
Run

这将分配构造 Vec<T> 所需的次数,然后分配一次,以将 Vec<T> 转换为 Rc<[T]>

已知长度的迭代器

当您的 Iterator 实现 TrustedLen 且大小正确时,将为 Rc<[T]> 进行一次分配。例如:

let evens: Rc<[u8]> = (0..10).collect(); // 这里只进行一次分配。
Run

获取 Iterator 中的每个元素,并将其收集到 Arc<[T]> 中。

性能特点

一般情况

在一般情况下,首先要收集到 Vec<T> 中来收集到 Arc<[T]> 中。也就是说,编写以下内容时:

let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0).collect();
Run

这就像我们写的那样:

let evens: Arc<[u8]> = (0..10).filter(|&x| x % 2 == 0)
    .collect::<Vec<_>>() // 第一组分配在此处发生。
    .into(); // `Arc<[T]>` 的第二个分配在此处进行。
Run

这将分配构造 Vec<T> 所需的次数,然后分配一次,以将 Vec<T> 转换为 Arc<[T]>

已知长度的迭代器

当您的 Iterator 实现 TrustedLen 且大小正确时,将为 Arc<[T]> 进行一次分配。例如:

let evens: Arc<[u8]> = (0..10).collect(); // 这里只进行一次分配。
Run