我刚开始使用rust,我尝试了一些数组方面的东西,但遇到了一些困难。第一个问题是初始化。我可以创建一个“空”数组,然后迭代元素来填充它,但我如何从一个范围初始化呢?
let mut arr: [i32; 5] = [0; 5]; // this works
// let mut arr: [i32; 5] = 1..5 //this doesn't
第二个问题是尝试从i32上的一个数组上的简单Map初始化一个数组。
let mut arr2: [i32; 5] = arr.iter().map(|&x| x + 1).collect();
实际上,即使打印(没有赋值)也不起作用:
println!("{:?}", arr.iter().map(|&x| x + 1).collect());
// the above fails with: "type annotations needed: cannot infer type for type arameter `B` declared on the associated function `collect`"
有什么至理名言吗?
2条答案
按热度按时间hmae6n7t1#
这里的一般问题是数组有固定的大小,在编译时已知,但迭代器中的项数在编译时是未知的--即使它是
ExactSizeIterator
,也没有常量参数表示大小,因此,从迭代器到数组的转换是不存在的。然而,也有一些 * fallible * 转换可用,其中最简单的一个是
impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N]
,它允许你将一个Vec<T>
转换为[T; N]
,如果向量的长度不正确,转换就会失败。这样做的缺点是为
Vec
分配临时堆并丢弃它。如果您确实希望数组在堆中存在,那么您可能希望使用TryFrom<Box<[T], Global>> for Box<[T; N], Global>
,它允许您从装箱切片中获取装箱数组。如果你想让数组被堆栈分配并且避免临时分配,那么你必须使用
std::iter::from_fn()
,这有点笨拙:(If你对长度很有信心,那么之后就没有必要Assert,但是内部的expect/unwrap是不可避免的。)
第二个问题是尝试从i32上的一个数组上的简单Map初始化一个数组。
这不起作用的原因与第一个相同:你现在不能直接收集到一个数组中。我上面提到的任何一种技术都适用于这种情况。
由于这个问题和答案是最初编写的,数组现在获得了一个方法
map
,您可以使用它来完成此操作,而无需通过迭代器:实际上,即使打印(没有赋值)也不起作用:
println!("{:?}", some_iterator.collect())
总是会失败,因为 * 你没有指定要收集到什么类型。*collect()
从不假设一个集合类型;它总是必须从上下文中指定或推断。如果你指定了一个类型,那么你可以打印迭代器的结果;原始输入是否是数组是无关紧要的。
dy2hfwbg2#
自 rust eclipse 1.63起
使用from_fn: