2

I wrote a "count all character occurrences in a string" function with Rust, but updating/adding to the values does not work with bracket notation. Why is that?

What works is this:

use std::collections::HashMap;

fn main() {
    let myString = "Go ahead and count all my characters";

    let mut myMap = HashMap::new();

    for ch in myString.chars() {
        *myMap.entry(ch).or_insert(0) += 1;
    }
}

What does NOT work is:

for ch in myString.chars() {
    myMap.entry(ch).or_insert(0);
    *myMap[&ch] += 1;
}

In the latter case, the compiler complains:

error[E0614]: type `{integer}` cannot be dereferenced
  --> src/main.rs:10:9
   |
10 |         *myMap[&ch] += 1;
   |         ^^^^^^^^^^^

This makes sense because they are copied and stored on the stack (if I understand correctly), but you also cannot add 1 to them if you do not try do dereference the value. It looks like the first version is the only option I have; is that correct? Why does it work there?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
niilz
  • 59
  • 1
  • 7

1 Answers1

3

In Rust the operators can be overloaded by the standard operator traits. The index operator (or sometimes called as subscript operator) has two flavours: Index and IndexMut. If you are looking at the documentation of the HashMap it only implements the former, thus it cannot modify the returned referenced value.

mcarton
  • 27,633
  • 5
  • 85
  • 95
Peter Varo
  • 11,726
  • 7
  • 55
  • 77
  • hashmap should not even implement Index according to index rule to cost O(1), that for example why string doesn't implement index. – Stargateur Jun 13 '19 at 23:05
  • 1
    @Stargateur what makes you think that? In theory accessing, inserting, and removing elements of a hash table have the average time complexity of O(1) and the worst case is O(n). Space complexity on the other hand is O(n). – Peter Varo Jun 13 '19 at 23:21
  • 1
    `O(1)` != `O(1)~` I don't like people always think access hashmap is `O(1)`, this simplify the problem too much and cause people to forget hashmap have a cost, and miss use it. Also, use index notation for hashmap can make it panic. Not very good too. Rust std break their own rule of index is O(1) by implementing index for hashmap. – Stargateur Jun 13 '19 at 23:30
  • 1
    You are comparing apples to pears. Hash table is indeed O(1): https://en.wikipedia.org/wiki/Hash_table – Peter Varo Jun 13 '19 at 23:32