我想在Rust中编写一个函数,该函数将返回由以下各项组成的向量:起始整数,然后是所有中间整数,然后是结束整数。它应该持有的断言是:
assert_eq!(intervals(0, 4, 1..4), vec![0, 1, 2, 3, 4]);
提示是使用迭代器的链方法。函数声明是预定义的,我以一种方式实现了它,它是以下代码:
pub fn intervals< I>(start: u32, end: u32, intermediate: I) -> Vec<u32>
where
I: IntoIterator<Item = u32>,
{
let mut a1 = vec![];
a1.push(start);
let inter: Vec<u32> = intermediate.into_iter().collect();
let mut iter : Vec<u32> = a1.iter().chain(inter.iter()).map(|x| *x).collect();
iter.push(end);
return iter;
}
但是我非常相信这不是实现此目的的最佳方法。我确定我在中间两行中做了很多不必要的事情。我试图像这样直接使用中间体:
let mut iter: Vec<u32> = a1.iter().chain(intermediate).map(|x| *x).collect();
但是我在使用链方法时遇到此错误,我不知道如何解决:
type mismatch resolving <I as std::iter::IntoIterator>::Item==&u32,
expected u32, found &u32
我在Rust中是超级新手,因此任何建议都将有助于理解此处使用中间参数的正确方法。
以下是一些提示:
collect
时,实际上只需要一个。std::iter::once
迭代器为起始整数和结束整数生成迭代器std::iter::once
参数实现intermediate
,因此您可以将其直接输入IntoIterator
。因此,您可以将开始,中间和结束链接在一起。应用这些技巧,您的功能将如下所示:
chain
另外要注意的一件事,是从评论中回答您的问题:
为什么要这样做:a1.iter()。chain(intermediate)给出链方法错误
调用chain
返回一个迭代器,该迭代器将references返回到向量中的值。这是有道理的:调用use std::iter::once;
pub fn intervals< I>(start: u32, end: u32, intermediate: I) -> Vec<u32>
where
I: IntoIterator<Item = u32>,
{
once(start).chain(intermediate).chain(once(end)).collect()
}
不会消耗向量,并且向量的内容保持不变:如果需要,您可以对其进行多次迭代。
另一方面,从Vec::iter()
特征调用iter()
将返回返回values的迭代器。这也很有意义:into_iter()
确实消耗了您正在调用它的对象,因此迭代器将对该对象先前拥有的项目拥有所有权。
尝试将两个这样的迭代器链接在一起是行不通的,因为它们每个都在迭代不同的类型。一种解决方案是也消耗a1,如下所示:
IntoIterator