Home > database >  Does the key of a HashMap have to be a pointer in Rust?
Does the key of a HashMap have to be a pointer in Rust?

Time:09-27

I'm admittedly new to Rust. That being said, this doesn't make sense to me yet finding out why the behavior I'm seeing isn't what I expect seems like a good learning opportunity:

use std::iter::Enumerate;
use std::collections::HashMap;
impl Solution {
    pub fn two_sum(nums: Vec<i32>, target: i32) -> Vec<i32> {
        let mut numToI: HashMap<i32, usize> = HashMap::new();
        for (i,v) in nums.iter().enumerate() {
            let num: i32 = *v;
            let complement: i32 = target - num;
            if numToI.contains_key(complement) {
                return vec![i as i32, numToI.get(complement) as i32];
            } else {
                numToI.insert(complement, i);
            }
        }
        return vec![-1,-1];
    }
}

Here I'm doing the simple question twoSum. I understand that nums.iter().enumerate() will return the values i and v, which are of type usize and a pointer to the element in nums (so in this case a reference to an i32), respectively. The thing I'm having trouble with is that although I specify numToI is a HashMap<i32, usize>, not HashMap<&i32, usize>, and I dereference to get the value of v with *v and assign the value to num, when I check if the HashMap numToI contains this i32 dereferenced value as a key, I get the error: expected &i32, found i32 on the call to contains_key. Why is this? Is it because the HashMap type always requires a pointer rather than a raw value, or is it due to an intricacy of Rust I'm not aware of? Shouldn't it expect a pointer for the key instead of a i32 if I had used HashMap<&i32, i32>?

More importantly, if this is due to a difference between Rust and C that has to do with the way borrowing etc. is used in Rust, where can I learn more about the intricacies of these differences?

CodePudding user response:

contains_key takes a reference. It doesn't need to take ownership of the value to test with - it just needs to look at it temporarily.

Rust is complaining that you are passing in an i32 by value instead of a reference to it. It should tell you to borrow instead: numToI.contains_key(&complement).

That's the only issue with your code, really. HashMap keys don't need to be references, and it would be really inconvenient if they did.

  • Related