gpt4 book ai didi

rust - Rust 中的 Chain Vector 和 IntoIterator 元素

转载 作者:行者123 更新时间:2023-11-29 08:23:10 29 4
gpt4 key购买 nike

我想用 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();

但是我在 chain 方法中遇到这个错误,我不知道如何解决:

type mismatch resolving <I as std::iter::IntoIterator>::Item==&u32, 
expected u32, found &u32

我是 Rust 的 super 新手,所以任何建议都有助于理解在这里使用中间参数的正确方法。

最佳答案

这里有一些提示:

  • 您创建了三个独立的向量(一个显式创建,两个使用 collect),而实际上您只需要一个。
  • 您可以使用 std::iter::once为开始和结束整数生成迭代器的迭代器
  • 无需收集中间范围。 intermediate 参数实现了 IntoIterator,因此您可以将其直接提供给 chain。 .因此,您可以将开始、中间和结束链接在一起。
  • 无需在函数末尾使用“return”关键字 - 函数的结果是其中最后一个表达式的值(只要末尾没有分号)。

应用这些技巧,您的函数将如下所示:

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()
}

需要注意的另一件事是从评论中回答您的问题:

why trying this: a1.iter().chain(intermediate) gives an error with chain method

调用 Vec::iter() 返回一个迭代器,该迭代器返回对向量中的值的引用。这是有道理的:调用 iter() 不会消耗向量,并且其内容保持不变:如果需要,您可以多次迭代它。

另一方面,从 IntoIterator 特征调用 into_iter() 会返回一个返回 的迭代器。这也是有道理的:into_iter() 确实会消耗您调用它的对象,因此迭代器随后会取得该对象之前拥有的项目的所有权。

尝试将两个这样的迭代器链接在一起是行不通的,因为它们各自迭代不同的类型。一种解决方案是也使用 a1,如下所示:

let mut iter : Vec<u32> = a1.into_iter().chain(intermediate).collect();

关于rust - Rust 中的 Chain Vector 和 IntoIterator 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58367776/

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