简体   繁体   English

在 Rust 中的 HashMap 中添加或增加值

[英]Add or increment value in HashMap in Rust

I am new to Rust and recently started learning.我是 Rust 的新手,最近开始学习。 I wrote a simple program which does the following.我写了一个简单的程序,它执行以下操作。

  1. Read a text file读取文本文件
  2. Split the words and store them in a HashMap with their occurrence count拆分单词并将它们存储在 HashMap 及其出现次数中
  3. Iterate over the map and print the word and occurrence count遍历 map 并打印单词和出现次数
use std::io;
use std::env;
use std::collections::HashMap;
use std::fs;

fn main() {
    let path = env::args().nth(1).unwrap();
    let contents = read_file(path);
    let map = count_words(contents);
    print(map);
}

fn read_file(path: String) -> (String){
    let contents =  fs::read_to_string(path).unwrap();
    return contents;
}

fn count_words(contents: String) -> (HashMap<String, i32>){
    let split = contents.split(&[' ', '\n'][..]);
    let mut map = HashMap::new();
    for w in split{
        if map.get(w) == None{
            map.insert(w.to_owned(), 1);
        }
        let count = map.get(w);
        map.insert(w.to_owned(), count + 1); // error here
    }
    return map;
}

fn print(map: HashMap<String, i32>){
    println!("Occurences..");

    for (key, value) in map.iter() {
        println!("{key}: {value}");
    }
}

I am able to read the file and add the words into a HashMap and print.我能够读取文件并将单词添加到 HashMap 并打印。 However, while trying to add or increment, I get below error.但是,在尝试添加或增加时,我得到以下错误。

error[E0369]: cannot add {integer} to Option<&{integer}> --> src\main.rs:27:40 |错误[E0369]:无法将{integer}添加到Option<&{integer}> --> src\main.rs:27:40 | 27 | 27 | map.insert(w.to_owned(), count + 1); map.insert(w.to_owned(), count + 1); | | ----- ^ - {integer} | ----- ^ - {整数} |
| | | | Option<&{integer}>选项<&{整数}>

I know this approach should work in other languages like Java, C# etc. but unsure about how it should work in Rust.我知道这种方法应该适用于其他语言,如 Java、C# 等,但不确定它应该如何在 Rust 中工作。

In this block:在这个块中:

if map.get(w) == None{
            map.insert(w.to_owned(), 1);
        }
        let count = map.get(w);
        map.insert(w.to_owned(), count + 1); // error here

map.get(w) gives you an Option<w> ( doc ); map.get(w)给你一个Option<w> ( doc );

You seem to know this to some extent, as you check if it's a None earlier - the other possibility is that it is what you want - a Some(w) (not just w );您似乎在某种程度上知道这一点,因为您之前检查它是否为None - 另一种可能性是它是您想要的 - Some(w) (不仅仅是w );

You cannot add an int to a Some , as the compiler tells you - you have to take "the w " (the count integer) out of the Some .正如编译器告诉您的那样,您不能将int添加到Some中 - 您必须从Some中取出“ w ”(计数整数)。


You can unwrap ( doc ), though it is not advisable.您可以unwrap ( doc ),但不建议这样做。


You can use pattern matching :您可以使用模式匹配

match map.get(&w) {
    Some(count) => { map.insert(w, count + 1); }
    None => { map.insert(w, 1); }
}

Or, written differently:或者,换一种写法:

if let Some(count) = map.get(&w) {
    map.insert(w, count + 1);
} else {
    map.insert(w, 1);
};

Or, better yet, you can use the Entry API , which turns it into a simple one liner:或者,更好的是,您可以使用条目 API ,将其变成一个简单的单行:

    *map.entry(w.to_owned()).or_default() += 1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM