我相信我在iter的数据类型和所有权方面都有问题。它首先在for循环表达式中声明。我相信Rust推断iter是u16类型的,因为它是在我第4行的计算中使用的。
1 let mut numbers: [Option<u16>; 5];
2 for iter in 0..5 {
3 let number_to_add: u16 = { // `iter` moves to inner scope
4 ((iter * 5) + 2) / (4 * 16) // Infers `iter: u16`
5 };
6
7 numbers[iter] = Some(number_to_add); // Expects `iter: usize`
8 } 我收到以下错误:
error[E0277]: the type `[std::option::Option<u16>]` cannot be indexed by `u16`
--> exercises/option/option1.rs:3:9
|
7 | numbers[iter] = Some(number_to_add);
| ^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`iter转换为u16,但仍然存在问题。我的误解在哪里?
发布于 2020-04-24 01:15:56
你的假设是正确的。而且您的修复也是好的(它导致了一个不同的错误,见下文)。
您的第一个问题是,对于切片索引,iter需要类型为usize,所以
numbers[iter as usize] = Some(number_to_add);或
((iter as u16 * 5) + 2) / (4 * 16)将导致通过锈蚀正确的类型推断。
第二个问题是数字没有初始化,所以当您试图修改数字时,rustc会正确地警告您。赋值,例如,
let mut numbers: [Option<u16>; 5] = [None; 5];会让你编译你的程序。
发布于 2020-04-24 07:10:32
除了现有的答案之外,更高层次的方法也可能更干净(取决于口味)。
let mut numbers = [None; 5];
for (i, n) in numbers.iter_mut().enumerate() {
let iter = i as u16;
let number_to_add: u16 =
((iter * 5) + 2) / (4 * 16);
*n = Some(number_to_add);
}另一种选择是更懒惰的方法,但是(afaik)没有办法(Afaik)将try_collect转换为数组,只能将try_from ()作为数组的一部分,因此您需要将()收集到vec,然后将try_from收集到数组,这似乎不太有用。尽管您总是可以使用迭代器初始化数组:
let mut it = (0u16..5).map(|i| ((i * 5) + 2) / (4 * 16));
let numbers = [it.next(), it.next(), it.next(), it.next(), it.next()];也是
//
iter移动到内部范围
iter是Copy,所以.抄袭。差不多吧。而且这个块也没有用,它只包含一个简单的表达式。
发布于 2020-04-24 07:21:28
你的推理是正确的。只是想添加一下,如果您只想初始化数组,也可以考虑这样做:
let arr_elem = |i: u16| Some(((i * 5) + 2) / (4 * 16));
let numbers : [Option<u16>; 5] = [
arr_elem(0),
arr_elem(1),
arr_elem(2),
arr_elem(3),
arr_elem(4),
];这样,您就不需要让它成为mut (代价是编写一个助手函数来初始化单个元素并声明初始化元素,但是这可以通过宏或一些辅助特性实现自动化)。
https://stackoverflow.com/questions/61398171
复制相似问题