Question
How can I create a HashMap literal in Rust?
In Python, I can write nested dictionary data like this:
hashmap = {
"element0": {
"name": "My New Element",
"childs": {
"child0": {
"name": "Child For Element 0",
"childs": {}
}
}
}
}
In Go, I can do something similar with a struct and a map:
type Node struct {
name string
childs map[string]Node
}
hashmap := map[string]Node{
"element0": Node{
"My New Element",
map[string]Node{
"child0": Node{
"Child For Element 0",
map[string]Node{}
},
},
},
}
What is the Rust equivalent for creating a HashMap, especially when the data is nested like this?
Short Answer
By the end of this page, you will understand why Rust does not have a built-in HashMap literal syntax like Python, and how to build HashMap values using HashMap::new(), insert(), arrays plus collect(), and helper macros. You will also see how to model nested data with structs and recursive types in idiomatic Rust.
Concept
Rust does not have a dedicated built-in literal syntax for HashMap values like Python's {} dictionary syntax. That is the key idea behind this question.
Instead, Rust usually creates HashMap values in one of these ways:
HashMap::new()and theninsert()items- build from an iterator using
.collect() - use a crate macro such as
maplit::hashmap!
Why Rust works this way
Rust keeps its core syntax small and explicit. A HashMap is not a special language construct. It is a type from the standard library:
use std::collections::HashMap;
Because it is a library type, Rust does not give it custom literal syntax the way arrays, tuples, or structs have.
Nested maps in Rust
When your data is nested, you usually have two design choices:
- Use nested
HashMaps directly - Use a struct for each node, and put nested
HashMaps inside the struct
For tree-like data such as your example, a struct is often clearer than storing everything as generic maps. It gives each field a name and a type.
Mental Model
Think of a HashMap in Rust like a filing cabinet you assemble before use.
In Python, the language gives you a ready-made shorthand for filling the cabinet instantly:
{"key": "value"}
In Rust, the cabinet is a normal library tool, not built into the language grammar. So you either:
- create an empty cabinet and add folders one by one, or
- prepare a list of
(key, value)pairs and convert it into a cabinet
For nested data, imagine each folder contains:
- a label (
name) - another smaller filing cabinet (
childs)
That is exactly what a recursive Node struct represents.
Syntax and Examples
Basic HashMap creation with insert
use std::collections::HashMap;
fn main() {
let mut map = HashMap::new();
map.insert("language", "Rust");
map.insert("type", "systems");
println!("{:?}", map);
}
Explanation
HashMap::new()creates an empty mapinsert(key, value)adds entries- the map must be
mutbecause inserting changes it
Building a HashMap with collect()
use std::collections::HashMap;
fn main() {
let map: HashMap<&str, > = [
(, ),
(, ),
(, ),
]
.()
.();
(, map);
}
Step by Step Execution
Consider this example:
use std::collections::HashMap;
#[derive(Debug)]
struct Node {
name: String,
childs: HashMap<String, Node>,
}
fn main() {
let leaf = Node {
name: "Child For Element 0".to_string(),
childs: HashMap::new(),
};
let mut child_map = HashMap::new();
child_map.insert("child0".to_string(), leaf);
let root = Node {
name: "My New Element".to_string(),
childs: child_map,
};
let mut nodes = HashMap::new();
nodes.insert("element0".to_string(), root);
println!("{:#?}", nodes);
}
What happens step by step
1. Define the Node type
Real World Use Cases
Configuration trees
Applications often load nested settings such as:
- services
- environment names
- feature flags
- child resources
A HashMap<String, Node> can represent a flexible hierarchy.
Menus and navigation
Desktop apps, games, and admin panels often model menus as nested nodes:
- menu label
- submenu items
That is very similar to a node with child maps.
File or category trees
You may need to represent:
- folders and subfolders
- product categories and subcategories
- comments and replies
A recursive struct with child maps is a common solution.
Parsing JSON-like data into typed Rust structures
Even if incoming data is dynamic, developers often convert it into structs for safety. A nested HashMap inside a struct can be useful when child keys are not fixed ahead of time.
Caches and lookup tables
Nested maps are also useful when data is grouped in stages, such as:
- country -> city -> weather record
- user_id -> resource_name -> permissions
- project -> file -> metadata
Real Codebase Usage
In real Rust codebases, developers rarely try to force everything into raw nested HashMaps unless the data is truly dynamic.
Common pattern: use structs for known fields
If fields like name are always present, use a struct:
struct Node {
name: String,
childs: HashMap<String, Node>,
}
This is clearer than storing "name" and "childs" as string keys inside another map.
Common pattern: build data in stages
Instead of writing one huge nested expression, many developers build values step by step:
- create child nodes
- put them into a child map
- create the parent node
- insert the parent into the outer map
This improves readability and makes debugging easier.
Common pattern: helper constructors
Projects often add helper functions:
use std::collections::HashMap;
#[derive(Debug)]
struct Node {
name: String,
childs: HashMap<String, Node>,
}
impl Node {
(name: &) {
{
name: name.(),
childs: HashMap::(),
}
}
}
Common Mistakes
1. Expecting Python-style map literals
Broken expectation:
// This is not valid Rust
let map = {
"a": 1,
"b": 2,
};
Why it fails
Rust does not have built-in HashMap literal syntax.
Fix
Use HashMap::new(), insert(), HashMap::from, or collect().
2. Forgetting to import HashMap
Broken code:
fn main() {
let map = HashMap::new();
}
Fix
use std::collections::HashMap;
3. Forgetting mut when inserting
Comparisons
HashMap::new() + insert() vs collect() vs macro
| Approach | Best for | Pros | Cons |
|---|---|---|---|
HashMap::new() + insert() | readable step-by-step building | explicit, easy to debug | more lines of code |
array/iterator + collect() | small fixed maps | compact, standard library only | can be less readable when deeply nested |
HashMap::from([...]) | simple fixed maps | very concise | not ideal for large nested values |
macro like hashmap! | literal-like style |
Cheat Sheet
Quick reference
Import
use std::collections::HashMap;
Empty map
let mut map: HashMap<String, i32> = HashMap::new();
Insert values
map.insert("a".to_string(), 1);
map.insert("b".to_string(), 2);
Build from fixed pairs
let map = HashMap::from([
("a", 1),
("b", 2),
]);
Build with collect()
let map: HashMap<&, > = [(, ), (, )].().();
FAQ
How do you create a HashMap literal in Rust?
Rust has no built-in HashMap literal syntax. You create maps with HashMap::new(), insert(), HashMap::from([...]), collect(), or a helper macro from a crate.
What is the closest thing to a dictionary literal in Rust?
For standard library code, HashMap::from([("a", 1), ("b", 2)]) is often the closest concise form for small maps.
Can a Rust struct contain a HashMap<String, Node> of itself?
Yes. A recursive type like that is valid because the HashMap stores its contents indirectly.
Should I use nested HashMaps or a struct in Rust?
Use a struct when fields are known, like name and childs. Use nested maps when keys or structure are dynamic.
Why does Rust require mut for HashMap::insert()?
Because insert() changes the map. Rust requires mutable bindings for values that will be modified.
Mini Project
Description
Build a small category tree in Rust using a recursive Node struct and nested HashMaps. This demonstrates how to model parent-child relationships in a strongly typed way, similar to menus, folder trees, or product categories.
Goal
Create a nested map of categories where each category has a name and zero or more child categories, then print the full structure.
Requirements
- Define a
Nodestruct with anamefield and achildsfield of typeHashMap<String, Node>. - Create at least one parent node and two child nodes.
- Store the parent node inside an outer
HashMap<String, Node>. - Print the final nested structure using debug output.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Can a Struct Extend Another Struct in Rust? Composition vs Inheritance
Learn how Rust handles struct reuse without inheritance, using composition, traits, and wrapper structs with practical examples.