gpt4 book ai didi

vector - 我如何在 Rust 中处理切片范围?

转载 作者:行者123 更新时间:2023-11-29 07:47:46 26 4
gpt4 key购买 nike

我知道在 Rust 中迭代的首选方法是通过 for var in (range) 语法,但有时我想处理该范围内的多个元素一次。

从 Ruby 的角度来看,我试图找到一种在 Rust 中执行 (1..100).each_slice(5) do |this_slice| 的方法。

我正在尝试类似的事情

for mut segment_start in (segment_size..max_val).step_by(segment_size) {
let this_segment = segment_start..(segment_start + segment_size).iter().take(segment_size);
}

但我不断收到错误消息,提示我正在寻找错误的 type 树。文档也没有帮助——它们只是不包含这个用例。

执行此操作的 Rust 方法是什么?

最佳答案

使用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 和 Rust 在这方面有不同的处理方式,主要以效率为中心。

在 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);
}
}

关于vector - 我如何在 Rust 中处理切片范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37033700/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com