使用chunks
(或chunks_mut
如果你需要的可變性):
fn main() {
let things = [5, 4, 3, 2, 1];
for slice in things.chunks(2) {
println!("{:?}", slice);
}
}
輸出:
[5, 4]
[3, 2]
[1]
這與Range
結合將收集的範圍內所涉及的最簡單方式Vec
第一個(對一個片段的解引用):
fn main() {
let things: Vec<_> = (1..100).collect();
for slice in things.chunks(5) {
println!("{:?}", slice);
}
}
另一種解決方案,它是純粹的迭代器是使用Itertools::chunks_lazy
:
extern crate itertools;
use itertools::Itertools;
fn main() {
for chunk in &(1..100).chunks_lazy(5) {
for val in chunk {
print!("{}, ", val);
}
println!("");
}
}
這表明類似的解決方案,只需要標準庫:
fn main() {
let mut range = (1..100).peekable();
while range.peek().is_some() {
for value in range.by_ref().take(5) {
print!("{}, ", value);
}
println!("");
}
}
一個訣竅是,Ruby和鏽病在這裏有不同的處理,主要集中在效率。
在Ruby中Enumerable
可以創建新數組來填充值,而不用擔心所有權並每次返回一個新數組(請檢查this_slice.object_id
)。
在Rust中,每次分配一個新的向量都是非常不尋常的。此外,由於複雜的生命期問題,您無法輕易地將引用返回給迭代器持有的向量。
這是非常相似的一種解決Ruby的是:
fn main() {
let mut range = (1..100).peekable();
while range.peek().is_some() {
let chunk: Vec<_> = range.by_ref().take(5).collect();
println!("{:?}", chunk);
}
}
其中可以在一個新的迭代器,隱藏的細節被包裹起來:
use std::iter::Peekable;
struct InefficientChunks<I>
where I: Iterator
{
iter: Peekable<I>,
size: usize,
}
impl<I> Iterator for InefficientChunks<I>
where I: Iterator
{
type Item = Vec<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
if self.iter.peek().is_some() {
Some(self.iter.by_ref().take(self.size).collect())
} else {
None
}
}
}
trait Awesome: Iterator + Sized {
fn inefficient_chunks(self, size: usize) -> InefficientChunks<Self> {
InefficientChunks {
iter: self.peekable(),
size: size,
}
}
}
impl<I> Awesome for I where I: Iterator {}
fn main() {
for chunk in (1..100).inefficient_chunks(5) {
println!("{:?}", chunk);
}
}
範圍沒有大塊,在至少不在stable中:'error:找不到名爲'chunks'的類型爲'core :: ops :: Range'的當前作用域' –
@TrevorAlexander我道歉;我讀得有點太快了!我添加了一些替代品。您可能想要向您的問題添加您的目標。根據我的經驗,我很少需要一堆數字。有可能有更好的整體方法。 – Shepmaster