首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解类型推理

理解类型推理
EN

Stack Overflow用户
提问于 2020-04-23 22:42:06
回答 3查看 245关注 0票数 1

我相信我在iter的数据类型和所有权方面都有问题。它首先在for循环表达式中声明。我相信Rust推断iteru16类型的,因为它是在我第4行的计算中使用的。

代码语言:javascript
复制
  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     }      

我收到以下错误:

代码语言:javascript
复制
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`

  • I尝试在第4行的计算中将iter转换为u16,但仍然存在问题。

我的误解在哪里?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-04-24 01:15:56

你的假设是正确的。而且您的修复也是好的(它导致了一个不同的错误,见下文)。

您的第一个问题是,对于切片索引,iter需要类型为usize,所以

代码语言:javascript
复制
numbers[iter as usize] = Some(number_to_add);

代码语言:javascript
复制
((iter as u16 * 5) + 2) / (4 * 16)

将导致通过锈蚀正确的类型推断。

第二个问题是数字没有初始化,所以当您试图修改数字时,rustc会正确地警告您。赋值,例如,

代码语言:javascript
复制
let mut numbers: [Option<u16>; 5] = [None; 5];

会让你编译你的程序。

票数 2
EN

Stack Overflow用户

发布于 2020-04-24 07:10:32

除了现有的答案之外,更高层次的方法也可能更干净(取决于口味)。

代码语言:javascript
复制
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收集到数组,这似乎不太有用。尽管您总是可以使用迭代器初始化数组:

代码语言:javascript
复制
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移动到内部范围

iterCopy,所以.抄袭。差不多吧。而且这个块也没有用,它只包含一个简单的表达式。

票数 0
EN

Stack Overflow用户

发布于 2020-04-24 07:21:28

你的推理是正确的。只是想添加一下,如果您只想初始化数组,也可以考虑这样做:

代码语言:javascript
复制
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 (代价是编写一个助手函数来初始化单个元素并声明初始化元素,但是这可以通过宏或一些辅助特性实现自动化)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61398171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档