rust阵列从范围或收集初始化

bt1cpqcv  于 2023-03-02  发布在  其他
关注(0)|答案(2)|浏览(137)

我刚开始使用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`"

有什么至理名言吗?

hmae6n7t

hmae6n7t1#

这里的一般问题是数组有固定的大小,在编译时已知,但迭代器中的项数在编译时是未知的--即使它是ExactSizeIterator,也没有常量参数表示大小,因此,从迭代器到数组的转换是不存在的。
然而,也有一些 * fallible * 转换可用,其中最简单的一个是impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N],它允许你将一个Vec<T>转换为[T; N],如果向量的长度不正确,转换就会失败。

use std::convert::TryInto;

let arr: [i32; 5] = (1..=5).collect::<Vec<_>>()
    .try_into().expect("wrong size iterator");

这样做的缺点是为Vec分配临时堆并丢弃它。如果您确实希望数组在堆中存在,那么您可能希望使用TryFrom<Box<[T], Global>> for Box<[T; N], Global>,它允许您从装箱切片中获取装箱数组。

let arr: Box<[i32; 5]> = (1..=5)
    .collect::<Box<[i32]>>()
    .try_into().expect("wrong size iterator");

如果你想让数组被堆栈分配并且避免临时分配,那么你必须使用std::iter::from_fn(),这有点笨拙:

let mut iter = 1..=5;
let arr: [i32; 5] = std::array::from_fn(|_| iter.next().expect("too short"));
assert!(iter.next().is_none(), "too long");

(If你对长度很有信心,那么之后就没有必要Assert,但是内部的expect/unwrap是不可避免的。)
第二个问题是尝试从i32上的一个数组上的简单Map初始化一个数组。

let mut arr2: [i32; 5] =  arr.iter().map(|&x| x + 1).collect();

这不起作用的原因与第一个相同:你现在不能直接收集到一个数组中。我上面提到的任何一种技术都适用于这种情况。
由于这个问题和答案是最初编写的,数组现在获得了一个方法map,您可以使用它来完成此操作,而无需通过迭代器:

let mut arr2: [i32; 5] = arr.map(|x| x + 1);

实际上,即使打印(没有赋值)也不起作用:
println!("{:?}", some_iterator.collect())总是会失败,因为 * 你没有指定要收集到什么类型。* collect()从不假设一个集合类型;它总是必须从上下文中指定或推断。
如果你指定了一个类型,那么你可以打印迭代器的结果;原始输入是否是数组是无关紧要的。

println!("{:?}", arr.iter().map(|&x| x + 1).collect::<Vec<_>>());
dy2hfwbg

dy2hfwbg2#

自 rust eclipse 1.63起

使用from_fn

let array: [usize; 5] = core::array::from_fn(|i| i + 1);
assert_eq!(array, [1, 2, 3, 4, 5]);

相关问题