Trait std::iter::FromIterator 1.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
fn from_iter<T>(iter: T) -> Self where
T: IntoIterator<Item = A>,
[src]
fn from_iter<T>(iter: T) -> Self where
T: IntoIterator<Item = A>,
[src]从迭代器创建一个值。
有关更多信息,请参见 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。
pub fn from_iter<T>(iter: T) -> Box<[I], Global>ⓘNotable traits for Box<I, A>impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
where
T: IntoIterator<Item = I>,
[src]impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S> where
K: Eq + Hash,
S: BuildHasher + Default,
[src]
impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S> where
K: Eq + Hash,
S: BuildHasher + Default,
[src]获取 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