Sajiron
Rust provides a rich standard library for collections, enabling developers to store, manage, and manipulate data efficiently. Three of the most fundamental collections you'll encounter are:
Vec<T>
– growable lists (like Java’s ArrayList
)
HashMap<K, V>
– key-value stores (like dictionaries or maps)
String
– dynamic, growable, UTF-8 encoded text
In this post, we’ll walk through how to use each of them with practical examples and detailed explanations.
Vec<T>
)Vectors in Rust are dynamic arrays that can grow or shrink in size. They store elements contiguously on the heap, which makes them efficient for indexed access and iteration. They're the go-to data structure for managing ordered lists of items.
let mut numbers = Vec::new();
numbers.push(1);
numbers.push(2);
numbers.push(3);
let letters = vec!['a', 'b', 'c'];
Vec::new()
creates an empty vector.
vec![...]
is the macro version — a convenient way to create a vector with initial values.
You can only push values of the same type (Vec
is generic over T
).
println!("{}", numbers[0]); // Direct index access
println!("{:?}", numbers.get(2)); // Safer access, returns Option<&T>
Using numbers[2]
panics if the index is out of bounds.
Using .get(index)
returns Some(&value)
or None
, which is safer and allows you to handle missing values explicitly.
for n in &numbers {
println!("{}", n);
}
You can iterate with for item in &vec
, which gives references.
Use for item in vec
if you want to consume the vector.
For mutable references: for item in &mut vec
.
numbers.pop(); // Removes and returns the last item
numbers.remove(0); // Removes element at a specific index
pop()
returns an Option<T>
, so you can check if it succeeded.
remove(index)
will panic if the index is invalid.
Useful when working with dynamic lists.
Efficient memory layout.
Built-in iteration and functional methods like .map()
, .filter()
with iter()
.
Rust has two main string types:
&str
: a borrowed string slice, usually used for static or borrowed string literals.
String
: an owned, growable, heap-allocated string type.
We mostly use String
when working with dynamic or modifiable text.
let mut s = String::from("Hello");
s.push(' ');
s.push_str("Rust!");
String::from
converts a string literal to a String
.
push(char)
adds a single character.
push_str(&str)
appends a string slice.
for c in s.chars() {
println!("{}", c);
}
let slice = &s[0..5]; // Gets "Hello"
s.chars()
returns an iterator over Unicode scalar values (characters).
Be cautious when slicing — slicing at invalid UTF-8 boundaries will panic.
let contains = s.contains("Rust");
let replaced = s.replace("Rust", "World");
let trimmed = s.trim();
contains
checks if a substring exists.
replace
replaces occurrences of a pattern.
trim
removes leading and trailing whitespace.
Strings in Rust are UTF-8 encoded, which means they can store international characters safely.
Strings must be managed carefully due to Rust’s safety guarantees — no nulls, and you must own or borrow properly.
The compiler helps catch common bugs around encoding, length, and indexing.
A HashMap<K, V>
is an unordered collection that maps keys to values. It uses a hashing algorithm to provide fast lookup, insert, and delete operations.
use std::collections::HashMap;
let mut scores = HashMap::new();
scores.insert("Alice", 90);
scores.insert("Bob", 85);
Keys and values must be of consistent types.
The insert()
method overwrites any existing value for the key.
if let Some(score) = scores.get("Alice") {
println!("Score: {}", score);
}
.get(key)
returns an Option<&V>
.
Always check for None
to avoid panics.
scores.insert("Alice", 95); // Overwrites Alice’s score
scores.entry("Charlie").or_insert(70); // Inserts only if key doesn't exist
.entry().or_insert()
is useful for initializing values if absent.
This is often used for word counts, grouping, or aggregating data.
for (name, score) in &scores {
println!("{}: {}", name, score);
}
Use a reference to avoid moving the map.
HashMap iteration order is not guaranteed (it's unordered).
Implementing a cache
Counting word frequencies
Mapping configuration values
Grouping and categorizing data
Collection | Use When... |
| You need an ordered, indexable list |
| You're storing or manipulating dynamic text |
| You need key-based lookups or mappings |
Think of these collections as building blocks for all kinds of applications — from simple scripts to complex systems.
Rust's collection types provide the perfect blend of safety, performance, and flexibility. In this post, you learned how to:
Build and modify growable arrays with Vec<T>
Create and manipulate text with String
Store and retrieve data using HashMap<K, V>
Understanding these will take you far in writing idiomatic, high-performance Rust programs.
Learn how to create, read, write, and manage files and directories in Rust with practical examples and error handling best practices.
Build fast and safe frontend apps using Rust and Yew. Learn setup, components, hooks, and WebAssembly—all in a React-like Rust framework.
Learn how to structure Rust projects with packages, crates, and modules for better maintainability, reusability, and scalability.
Learn Rust async/await with futures, concurrency, and Tokio runtime. Master non-blocking programming, async streams, and efficient task execution. 🚀