【问题标题】:for loop with `.collect()` cannot infer type带有 .collect() 的 for 循环无法推断类型
【发布时间】:2021-06-26 12:31:25
【问题描述】:

运行以下代码时,来自attempting the exercise in the Rust Book

代码

use std::collections::HashMap;

fn main() {
    let mut values = [5, 34, 31, 4, 31, 25, 28, 45, 43, 14];
    values.sort();

    let mut total = 0;
    let mut mode_collection = HashMap::new();
    let mut mode = HashMap::new();

    for value in values.iter() {

        let count = mode_collection.entry(value.clone()).or_insert(0);
        *count += 1;
        total += value;
    };

    for (value, count) in mode_collection.iter() {
        let count_values = mode.entry(count).or_insert(vec![]);
        count_values.push(value.clone());
    }

    let mut largest_count: i32 = 0;
    for count in mode.keys().collect() {
        if count > largest_count {
            largest_count = count;
        }
    }

    println!("The average of the values is {}", total / values.len());
    println!("The median of the values is {}", values[values.len() / 2]);
    println!("The mode of the values is {:?}", mode[&largest_count]);
}

In Rust Playground

错误

error[E0282]: type annotations needed
  --> src\main.rs:24:18
   |
24 |     for count in mode.keys().collect() {
   |                  ^^^^^^^^^^^^^^^^^^^^^ cannot infer type

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.
error: could not compile `enums`

To learn more, run the command again with --verbose.

尝试修复

据我所知,不能将类型注释添加到for 循环中。但是使用collect() 时需要类型注释。当我摆脱 collect() count&&{Integer} (双借整数?)所以 largest_countcount 变量无法比较。

【问题讨论】:

    标签: rust


    【解决方案1】:
    1. 如果需要显式类型注释,可以使用下一个语义:
    for count in mode.keys().collect::<Vec<_>>() {
       // do stuff over each count
    }
    
    1. 您无需收集项目即可在for 循环中对其进行迭代。 mode.keys() 已经是一个迭代器,所以你可以写:
    for count in mode.keys() {
        // do stuff
    }
    
    1. 如果您需要从迭代器中获取单个结果,最好使用fold
    let largest_count = mode.keys().copied().fold(0, |largest, current| largest.max(current));
    
    1. 在您的特定情况下,您可以只写:
    let largets_count = mode.keys().copied().max();
    

    【讨论】:

    • 感谢您的帮助!为了让#4 工作,我需要添加一个expect,因为返回了一个Option。这是我用的let largest_count = mode.keys().copied().max().expect("There are no values!"); 这是playground
    【解决方案2】:

    您在这里遇到了两个问题:

    1. collect() 失败,因为无法知道生成的集合应该具有什么类型。您可以通过the turbo-fish 将类型注释为mode.keys().collect::&lt;Vec&lt;_&gt;&gt;()。这不会解决您的问题,因为它不会改变所收集物品的类型。
    2. 您可以简单地取消引用循环中的整数。这将解决您的问题,并且根本不需要收集。 IE。 **count&amp;&amp;i32 转换为 i32 并允许您按预期进行比较。

    您可能还想重新考虑在哈希图中存储对整数的引用,然后您可以通过在 keys() 迭代器上调用 copied() 来解决问题。

    【讨论】:

    • ** 工作! play.rust-lang.org/…
    • 或者你可以在模式匹配中取消引用:for &amp;&amp;count in mode.keys()
    • 可能更可取,因为这是一次取消引用,而不必在所有地方都这样做。
    • 我的理解是&amp;使它成为借用/参考,但这似乎是错误的。在变量声明中使用&amp; 就像说这 is 借用/引用?
    • 在那个位置是模式匹配,所以你正在解构双重引用的值并直接访问该值
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    相关资源
    最近更新 更多