Reputation: 63
I'm using a HashMap
to store some important data, and I want to be able to look for a certain key, insert a value for it if it doesn't exist, and do stuff to the value if the key was found.
I stripped down the code to a minimal reproduction of the error, I'm not really trying to increment numbers. I do want to use the HashMap::Entry
capabilities, iterating over all keys/values is not an alternative.
use std::collections::HashMap;
pub fn stack_overflow_example() -> bool {
let hash_map: HashMap<i32, i32> = HashMap::new();
let key = 1;
match hash_map.entry(key) {
HashMap::Entry::Vacant(entry) => entry.insert(vec![1]),
HashMap::Entry::Occupied(entry) => {
let mut numbers = entry.into_mut().iter_mut();
let mut numbers_affected = 0;
for number in numbers {
if number < 10 {
number = number + 1;
numbers_affected += 1;
}
}
if numbers_affected == 0 {
numbers.push(1)
}
}
}
true
}
I get this error message:
error[E0223]: ambiguous associated type
--> src/main.rs:8:9
|
8 | HashMap::Entry::Vacant(entry) => entry.insert(vec![1]),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
|
= note: specify the type using the syntax `<std::collections::HashMap<_, _, _> as Trait>::Entry`
error[E0223]: ambiguous associated type
--> src/main.rs:9:9
|
9 | HashMap::Entry::Occupied(entry) => {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ambiguous associated type
|
= note: specify the type using the syntax `<std::collections::HashMap<_, _, _> as Trait>::Entry`
I tried doing what it says, but when I put those changes in, I can't put (entry)
after Vacant
and Occupied
. Here is the error message:
error: unexpected `(` after qualified path
--> src/main.rs:8:69
|
8 | <std::collections::HashMap<_, _, _> as Trait>::Entry::Vacant(entry) => entry.insert(vec![1]),
| ^
Should I really use 'Trait' literally? I don't know. Should I replace the underscores with the relevant types? Likely, yes, but I still get the same error.
Upvotes: 5
Views: 1180
Reputation: 431689
There is a simple typo. Refer to the documentation for Entry
:
std::collections::hash_map::Entry
You want to use something like
match hash_map.entry(key) {
std::collections::hash_map::Entry::Vacant(entry) => (),
std::collections::hash_map::Entry::Occupied(entry) => (),
}
Although it's normally
use std::collections::hash_map::Entry;
match hash_map.entry(key) {
Entry::Vacant(entry) => (),
Entry::Occupied(entry) => (),
}
This unlocks many other errors in the code:
i32
as the value.Note that often you don't even need to match on Entry
explicitly. Seems like the code should be
pub fn stack_overflow_example(hash_map: &mut HashMap<i32, Vec<i32>>) {
let mut numbers_affected = 0;
let numbers = hash_map.entry(1).or_insert_with(Vec::new);
for number in numbers.iter_mut() {
if *number < 10 {
*number += 1;
numbers_affected += 1;
}
}
if numbers_affected == 0 {
numbers.push(1)
}
}
Upvotes: 4