boo*_*gie 13 arrays iteration rust
刚开始使用 Rust,我正在尝试一些数组的东西,但遇到了一些困难。第一个问题是初始化。我可以创建一个“空”数组并迭代元素来填充它,但如何从范围初始化?:
let mut arr: [i32; 5] = [0; 5]; // this works
// let mut arr: [i32; 5] = 1..5 //this doesn't
Run Code Online (Sandbox Code Playgroud)
第二个问题是尝试通过 i32 上的数组的简单映射来初始化数组。这不起作用:
let mut arr2: [i32; 5] = arr.iter().map(|&x| x + 1).collect();
Run Code Online (Sandbox Code Playgroud)
事实上,即使打印(不分配)也不起作用:
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`"
Run Code Online (Sandbox Code Playgroud)
有什么智慧的话可以提供吗?
aed*_*edm 25
使用from_fn:
let array: [usize; 5] = core::array::from_fn(|i| i + 1);
assert_eq!(array, [1, 2, 3, 4, 5]);
Run Code Online (Sandbox Code Playgroud)
Kev*_*eid 14
这里的一般问题是数组具有固定大小,在编译时已知,但迭代器中的项数在编译时未知 \xe2\x80\x94 即使它是一个ExactSizeIterator,也有没有大小常量参数。因此,不存在从迭代器到数组的绝对正确的转换。
然而,也存在一些容易出错的转换。最直接常用的是impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N],它允许您将 a 转换Vec<T>为[T; N],如果向量长度错误则失败。
use std::convert::TryInto;\n\nlet arr: [i32; 5] = (1..=5).collect::<Vec<_>>()\n .try_into().expect("wrong size iterator");\nRun Code Online (Sandbox Code Playgroud)\n这样做的缺点是需要为 进行临时堆分配Vec并丢弃它。如果您确实希望数组位于堆上,那么您可能需要使用TryFrom<Box<[T], Global>> for Box<[T; N], Global>它,它允许您从装箱切片中获取装箱数组。
let arr: Box<[i32; 5]> = (1..=5)\n .collect::<Box<[i32]>>()\n .try_into().expect("wrong size iterator");\nRun Code Online (Sandbox Code Playgroud)\n如果您希望数组被堆栈分配并避免临时分配,那么您将不得不使用std::iter::from_fn(),有点尴尬:
let mut iter = 1..=5;\nlet arr: [i32; 5] = std::array::from_fn(|_| iter.next().expect("too short"));\nassert!(iter.next().is_none(), "too long");\nRun Code Online (Sandbox Code Playgroud)\n(如果您对长度有信心,则无需事后断言,但内部的期望/展开是不可避免的。)
\n\n\n第二个问题是尝试通过 i32 上的数组的简单映射来初始化数组。这不起作用:
\nRun Code Online (Sandbox Code Playgroud)\nlet mut arr2: [i32; 5] = arr.iter().map(|&x| x + 1).collect();\n
这不起作用的原因与第一个相同:您当前无法直接收集到数组中。我上面提到的任何技术也适用于这种情况。
\n由于这个问题和答案最初是写的,数组现在获得了一种方法map,您可以使用它来执行此操作,而无需通过迭代器:
let mut arr2: [i32; 5] = arr.map(|x| x + 1);\nRun Code Online (Sandbox Code Playgroud)\n\n\n事实上,即使打印(不分配)也不起作用:
\n
这实际上是一个与其他问题不同的问题。println!("{:?}", some_iterator.collect())总是会失败,因为您没有指定要收集到的类型。 collect()从不假设集合类型;它总是必须从上下文中指定或推断。
如果指定类型,则可以打印迭代器的结果;原始输入是否是数组无关紧要。
\nprintln!("{:?}", arr.iter().map(|&x| x + 1).collect::<Vec<_>>());\nRun Code Online (Sandbox Code Playgroud)\n