1

I have a struct that is created with an empty HashMap (node_type_odds). This hashmap will have values added by the user.

When I attempt to add keys and values to the hashmap after creation using fn set_node_odds it does not suggest the insert keyword which (as I understand it) is the primary way keys are inserted into hashmaps.

Why can't I add values to a hashmap that is contained in a struct?

use std::collections::HashMap;

//The possible node types
pub(crate) enum node_type {
    Kernel,
    LSTM,
    Perceptron,
}

//The possible activation types
pub(crate) enum activation_type {
    Binary,
    Linear,
    Sigmoid,
    Tan,
}

//The constructor that holds the seed values for the Mesh Networks.
pub(crate) struct constructor {
    node_type_default: node_type,
    node_type_odds: HashMap<node_type, f32>,
    activation_type: activation_type,
}

impl constructor {
    //Set the default node and initialize default values
    pub(crate) fn new() -> constructor {
        constructor {
            node_type_default: node_type::Perceptron,
            node_type_odds: HashMap::new(),
            activation_type: activation_type::Sigmoid,
        }
    }

    //Set the default node to a custom value
    pub(crate) fn set_default_node(&mut self, default_node: node_type) {
        self.node_type_default = default_node;
    }

    //Set the odds of each type of node to appear
    pub(crate) fn set_node_odds(&mut self, Type: node_type, Value: f32) {
        **//Here I attempt to insert a value with the key of type and a value of X.
  //Insert is not suggested however.**

        //THIS CODE SNIPPET DOES NOT WORK AS INSERT IS NOT SUGGESTED, IT IS HOWEVER THE INTENDED RESULT
        self.node_type_odds.insert(Type, Value);
    }
}
error[E0599]: no method named `insert` found for struct `std::collections::HashMap<constructor::node_type, f32>` in the current scope
  --> src/constructor.rs:45:29
   |
4  | pub(crate) enum node_type {
   | -------------------------
   | |
   | doesn't satisfy `constructor::node_type: std::cmp::Eq`
   | doesn't satisfy `constructor::node_type: std::hash::Hash`
...
45 |         self.node_type_odds.insert(node_type::Perceptron, 3 as f32);
   |                             ^^^^^^ method not found in `std::collections::HashMap<constructor::node_type, f32>`
   |
   = note: the method `insert` exists but the following trait bounds were not satisfied:
           `constructor::node_type: std::cmp::Eq`
           `constructor::node_type: std::hash::Hash`
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 1
    By the way, idiomatic Rust uses `snake_case` for variables, methods, macros, fields and modules; `UpperCamelCase` for types and enum variants; and `SCREAMING_SNAKE_CASE` for statics and constants. – Shepmaster Jul 20 '20 at 18:40
  • 2
    You need to implement `Eq` and `Hash` on `node_type`, otherwise the hash map is basically useless. – Sven Marnach Jul 20 '20 at 18:42
  • It looks like your question might be answered by the answers of [What does it mean when “method exists but trait bounds not satisfied”?](https://stackoverflow.com/q/56296864/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jul 20 '20 at 18:43
  • 2
    The error message from the compiler would actually tell you that's the problem. – Sven Marnach Jul 20 '20 at 18:43
  • It does not, otherwise I wouldn't be here. – Christian Potts Jul 20 '20 at 18:43
  • *otherwise I wouldn't be here* — people ask questions about why their IDE doesn't do X or Y all the time; your question doesn't clearly indicate what it is you are asking. – Shepmaster Jul 20 '20 at 18:47
  • Sven Marnach, that could be the issue. Ill see if it fixes the problem. – Christian Potts Jul 20 '20 at 18:48
  • Can you expand a bit more what you don't understand about the error message? *`insert` exists but the following trait bounds were not satisfied: `node_type: Eq` `node_type: Hash`* feels understandable to me. – Shepmaster Jul 20 '20 at 18:49
  • Literally everything you just said. Chapter 8.3 of the documentation did not mention the need to implement traits to change a HashMap. – Christian Potts Jul 20 '20 at 18:52
  • 2
    The key type of the hash map needs to implement these traits. If you use, say, `String` or `i32` as the key type, you don't need to implement these tratis since they are already implemented. If you want to use a custom type as the key type of the hash map, you need to implement the traits yourself, but you can most of the time get away with simply deriving them. – Sven Marnach Jul 20 '20 at 19:01
  • Yup. It's a hard requirement based on the implementation of a *hash*map — the keys need to be able to be hashed. They also need to be able to be compared for equality, as multiple unique values might hash to the same key. – Shepmaster Jul 20 '20 at 19:02
  • Thank you for the clarification Sven and Shepmaster. This has shown me that I may need to take another approach to this problem. – Christian Potts Jul 20 '20 at 19:11

0 Answers0