1

I am working on a program in Rust and I am getting stuck on match. I currently have

extern crate regex;

use std::collections::HashMap;

fn main() {
    let s = "";

    let re = regex::Regex::new(r"[^A-Za-z0-9\w'").unwrap();
    let s = re.split(s).collect::<Vec<&str>>();
    let mut h: HashMap<String, u32> = HashMap::new();
    for x in s {
        match h.get(x) {
            Some(i) => h.entry(x.to_string()).or_insert_with(i + 1),
            None => h.entry(x.to_string()).or_insert_with(1),
        }
    }
}

but when I run this I get a whole litany of errors, including

error: the trait bound `u32: std::ops::FnOnce<()>` is not satisfied [E0277]
            Some(i) => h.entry(x.to_string()).or_insert_with(i + 1),
                                              ^~~~~~~~~~~~~~

and I'm not exactly sure where to go with this.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Eli Sadoff
  • 7,173
  • 6
  • 33
  • 61
  • See also [How to lookup from and insert into a HashMap efficiently?](http://stackoverflow.com/q/28512394/155423) – Shepmaster Jun 21 '16 at 02:43

1 Answers1

3

The or_with family of functions expect a function that returns the values as a parameter. You want .or_insert, which directly expects the value:

let re = regex::Regex::new(r"[^A-Za-z0-9\w'").unwrap();
let s = re.split(s).collect::<Vec<&str>>();
let mut h: HashMap<String, u32> = HashMap::new();
for x in s {
    match h.get(x) {
      Some(i) => h.entry(x.to_string()).or_insert(i + 1),
      None    => h.entry(x.to_string()).or_insert(1),
    }
}

Anyway, you are missing the point of the Entry API:

let re = regex::Regex::new(r"[^A-Za-z0-9\w'").unwrap();
let s = re.split(s).collect::<Vec<&str>>();
let mut h: HashMap<String, u32> = HashMap::new();
for x in s {
    match h.entry(x.to_string()) {
      Entry::Vacant(v)   => {
          v.insert(1);
      },
      Entry::Occupied(o) => {
          *o.into_mut() += 1;
      },
    }
}
mcarton
  • 27,633
  • 5
  • 85
  • 95