Staring at Rust code feels safe. Writing it feels scary.
That’s where the real learning begins — and this post is built to take you from reading to doing with genuine confidence.
Here’s what’s waiting for you:
- 100 Rust practice problems, from absolute basics to real-world patterns.
- Clear, step-by-step solutions — never just “here’s the answer,” always “here’s why it works.”
- Challenges packed with ownership, borrowing, lifetimes, enums, pattern matching, traits, and concurrency.
How it works:
- Read the plain-language problem.
- Try solving it yourself — yes, struggle a little, that’s growth.
- Check the solution and understand the logic deeply.
- Repeat until writing idiomatic Rust feels natural.
Why does practice matter so much? Rust is a language that rewards muscle memory and clear mental models. Every problem you solve makes ownership rules second nature, turns compiler messages into friendly hints, and builds the kind of skill that technical interviews and production code demand.
Whether you’re falling in love with systems programming or preparing for your next big role, these exercises will make you feel capable, creative, and ready. Pick a problem. Start today. Your “I really get Rust now!” moment is closer than you think.
Also try it: 100 C++ practice problems with solutions
1. Hello, World!
Print “Hello, World!” to the console.
rust
fn main() {
println!("Hello, World!");
}
2. Declare Mutable and Immutable Variables
Create an immutable variable x with value 5, and a mutable variable y with value 10, then print them.
rust
fn main() {
let x = 5;
let mut y = 10;
println!("x = {}, y = {}", x, y);
y = 15;
println!("y = {}", y);
}
3. Basic Function
Write a function add that takes two integers and returns their sum.
rust
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
println!("3 + 5 = {}", add(3, 5));
}
4. If‑else Condition
Write a function that returns "even" if a number is even, "odd" otherwise.
rust
fn even_or_odd(n: i32) -> &'static str {
if n % 2 == 0 {
"even"
} else {
"odd"
}
}
5. Loop to Sum 1..100
Compute the sum of integers from 1 to 100 using a loop.
rust
fn main() {
let mut sum = 0;
let mut n = 1;
loop {
sum += n;
n += 1;
if n > 100 { break; }
}
println!("Sum = {}", sum);
}
6. For Loop Over Range
Print numbers from 1 to 5 using a for loop.
rust
fn main() {
for i in 1..=5 {
println!("{}", i);
}
}
7. While Loop Factorial
Calculate factorial of 5 using a while loop.
rust
fn main() {
let mut n = 5;
let mut fact = 1;
while n > 0 {
fact *= n;
n -= 1;
}
println!("5! = {}", fact);
}
8. String Slicing
Given a string literal, return the first word (characters until a space).
rust
fn first_word(s: &str) -> &str {
match s.split_whitespace().next() {
Some(word) => word,
None => s,
}
}
fn main() {
println!("{}", first_word("Hello world"));
}
9. Ownership: Move Semantics
Create a String, move it to a new variable, and show that the old variable cannot be used.
rust
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1 moved
// println!("{}", s1); // error!
println!("{}", s2);
}
10. Borrowing with References
Write a function that takes a reference to a String and prints its length without taking ownership.
rust
fn print_length(s: &String) {
println!("Length: {}", s.len());
}
fn main() {
let s = String::from("hello");
print_length(&s);
println!("Still own: {}", s);
}
11. Mutable Reference
Write a function that pushes a character to a mutable String.
rust
fn add_exclamation(s: &mut String) {
s.push('!');
}
fn main() {
let mut text = String::from("Hello");
add_exclamation(&mut text);
println!("{}", text);
}
12. Dangling Reference (Prevented by compiler)
Comment: Rust prevents returning a reference to a local variable.
rust
// This won't compile:
// fn dangle() -> &String {
// let s = String::from("hello");
// &s
// }
// Instead return the String directly.
fn no_dangle() -> String {
String::from("hello")
}
13. Struct Definition and Instantiation
Define a Rectangle struct with width and height, and create an instance.
rust
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("{}x{}", rect.width, rect.height);
}
14. Struct Method
Implement a method area for Rectangle.
rust
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("Area = {}", rect.area());
}
15. Struct Associated Function
Add an associated function square(size) that returns a Rectangle with equal width and height.
rust
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle { width: size, height: size }
}
}
fn main() {
let sq = Rectangle::square(25);
println!("Square: {}x{}", sq.width, sq.height);
}
16. Tuple Struct
Define a Color tuple struct with r, g, b and create an instance.
rust
struct Color(u8, u8, u8);
fn main() {
let red = Color(255, 0, 0);
println!("Red: {}, {}, {}", red.0, red.1, red.2);
}
17. Enums: Basic
Define an enum IpAddrKind with V4 and V6 variants and create instances.
rust
enum IpAddrKind {
V4,
V6,
}
fn main() {
let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
}
18. Enum with Data
Make the enum hold the actual address: V4(u8,u8,u8,u8) and V6(String).
rust
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
fn main() {
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
}
19. Enum Method
Implement a method describe for a TrafficLight enum (Red, Yellow, Green) that returns a description.
rust
enum TrafficLight {
Red,
Yellow,
Green,
}
impl TrafficLight {
fn describe(&self) -> &str {
match self {
TrafficLight::Red => "Stop",
TrafficLight::Yellow => "Caution",
TrafficLight::Green => "Go",
}
}
}
20. Match with Exhaustive Arms
Write a function that takes an Option<i32> and returns the value inside, or 0 if None.
rust
fn unwrap_or_zero(opt: Option<i32>) -> i32 {
match opt {
Some(val) => val,
None => 0,
}
}
21. If-let Pattern
Use if let to print the value inside an Option only if it’s Some.
rust
fn main() {
let config_max = Some(3u8);
if let Some(max) = config_max {
println!("Max = {}", max);
}
}
22. While-let Pattern
Use while let to pop values from a vector until empty.
rust
fn main() {
let mut stack = vec![1, 2, 3];
while let Some(top) = stack.pop() {
println!("{}", top);
}
}
23. Vector Basics
Create a vector, push elements, and access by index.
rust
fn main() {
let mut v = Vec::new();
v.push(10);
v.push(20);
println!("First: {}", v[0]); // panics if oob
println!("Get: {:?}", v.get(1)); // Some(20)
}
24. Iterate Over Vector
Use a for loop to print all elements.
rust
fn main() {
let v = vec![1, 2, 3, 4, 5];
for i in &v {
println!("{}", i);
}
}
25. Modify Vector Elements via Mutable Iteration
Double each element in a Vec<i32>.
rust
fn main() {
let mut v = vec![1, 2, 3];
for i in &mut v {
*i *= 2;
}
println!("{:?}", v); // [2, 4, 6]
}
26. String: Creating and Concatenating
Build a String by pushing a string slice and pushing a char.
rust
fn main() {
let mut s = String::from("Hello");
s.push_str(" world");
s.push('!');
println!("{}", s);
}
27. String Format
Use format! to combine strings without moving ownership.
rust
fn main() {
let s1 = String::from("Hello");
let s2 = String::from("World");
let combined = format!("{} {}", s1, s2);
println!("{}", combined);
println!("s1 still: {}", s1); // s1 not moved
}
28. Hash Map: Insert and Access
Create a HashMap and insert key-value pairs; then access a key.
rust
use std::collections::HashMap;
fn main() {
let mut scores = HashMap::new();
scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
println!("{:?}", scores.get("Blue")); // Some(10)
}
29. Hash Map: Entry API
Count occurrences of words in a sentence.
rust
fn main() {
let text = "hello world hello rust";
let mut map = HashMap::new();
for word in text.split_whitespace() {
let count = map.entry(word).or_insert(0);
*count += 1;
}
println!("{:?}", map);
}
30. Result Type: Basic Handling
Write a function that converts a string to an integer, returning a Result.
rust
fn parse_number(s: &str) -> Result<i32, std::num::ParseIntError> {
s.parse::<i32>()
}
fn main() {
match parse_number("42") {
Ok(n) => println!("Number: {}", n),
Err(e) => println!("Error: {}", e),
}
}
31. Unwrapping and Expect
Use unwrap and expect on a valid Option.
rust
fn main() {
let x = Some(5);
println!("{}", x.unwrap());
println!("{}", x.expect("Should have value"));
}
32. Propagating Errors with ?
Write a function that reads the first line of a file and returns the length, using ? to propagate errors.
rust
use std::fs;
fn file_first_line_length(path: &str) -> Result<usize, std::io::Error> {
let content = fs::read_to_string(path)?;
Ok(content.lines().next().unwrap_or("").len())
}
33. Custom Error Type with Debug and Display
Create a simple custom error struct and implement traits.
rust
#[derive(Debug)]
struct MyError {
msg: String,
}
impl std::fmt::Display for MyError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "MyError: {}", self.msg)
}
}
impl std::error::Error for MyError {}
fn main() {
let err = MyError { msg: String::from("something wrong") };
println!("{}", err);
}
34. Generic Function: Largest
Write a generic function largest<T: PartialOrd + Clone> that returns the largest element from a slice.
rust
fn largest<T: PartialOrd + Clone>(list: &[T]) -> T {
let mut largest = list[0].clone();
for item in list.iter() {
if item > &largest {
largest = item.clone();
}
}
largest
}
fn main() {
let numbers = vec![3, 5, 2, 8, 1];
println!("Largest: {}", largest(&numbers));
}
35. Generic Struct
Define a Point struct with two fields of generic type T.
rust
struct Point<T> {
x: T,
y: T,
}
fn main() {
let integer_point = Point { x: 5, y: 10 };
let float_point = Point { x: 1.0, y: 4.0 };
}
36. Method with Generic Type and Constraints
Implement a method x on Point<T> that returns a reference to x.
rust
impl<T> Point<T> {
fn x(&self) -> &T {
&self.x
}
}
37. Traits: Define and Implement
Define a trait Summary with a method summarize, and implement it for NewsArticle.
rust
trait Summary {
fn summarize(&self) -> String;
}
struct NewsArticle {
headline: String,
author: String,
}
impl Summary for NewsArticle {
fn summarize(&self) -> String {
format!("{} by {}", self.headline, self.author)
}
}
38. Trait Bound Function
Write a function that takes any type implementing Summary and prints it.
rust
fn notify(item: &impl Summary) {
println!("Breaking news! {}", item.summarize());
}
39. Derivable Traits
Use #[derive(Debug, Clone, PartialEq)] on a struct.
rust
#[derive(Debug, Clone, PartialEq)]
struct User {
name: String,
age: u8,
}
fn main() {
let u1 = User { name: String::from("Alice"), age: 30 };
let u2 = u1.clone();
println!("{:?}", u2);
assert_eq!(u1, u2);
}
40. Lifetimes in Functions
Write a function longest that returns the longer of two string slices, using explicit lifetime annotation.
rust
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}
fn main() {
let s1 = "hello";
let s2 = "world!";
println!("Longer: {}", longest(s1, s2));
}
41. Iterator: Map and Collect
Take a vector, apply map to double each element, and collect into a new vector.
rust
fn main() {
let v = vec![1, 2, 3, 4, 5];
let doubled: Vec<i32> = v.iter().map(|x| x * 2).collect();
println!("{:?}", doubled);
}
42. Filtering
From a vector of integers, filter out the even numbers.
rust
fn main() {
let nums = vec![1, 2, 3, 4, 5, 6];
let odds: Vec<_> = nums.into_iter().filter(|x| x % 2 != 0).collect();
println!("{:?}", odds);
}
43. Fold (Reduce)
Sum all elements using fold.
rust
fn main() {
let numbers = [1, 2, 3, 4, 5];
let sum = numbers.iter().fold(0, |acc, x| acc + x);
println!("Sum = {}", sum);
}
44. Any and All
Check if all numbers are positive and if any is even.
rust
fn main() {
let v = vec![2, 4, 6];
let all_positive = v.iter().all(|&x| x > 0);
let any_even = v.iter().any(|&x| x % 2 == 0);
println!("All positive: {}, Any even: {}", all_positive, any_even);
}
45. Enumerate
Iterate with index using enumerate.
rust
fn main() {
let names = vec!["Alice", "Bob", "Carol"];
for (i, name) in names.iter().enumerate() {
println!("{}. {}", i + 1, name);
}
}
46. Chaining Iterator Methods
Take a vector of words, filter those with length > 3, convert to uppercase, collect.
rust
fn main() {
let words = vec!["hi", "hello", "rust", "ok"];
let result: Vec<_> = words.into_iter()
.filter(|w| w.len() > 3)
.map(|w| w.to_uppercase())
.collect();
println!("{:?}", result);
}
47. Closures: Capture Environment
Create a closure that captures a variable and increments it.
rust
fn main() {
let mut count = 0;
let mut inc = || {
count += 1;
count
};
println!("{}", inc()); // 1
println!("{}", inc()); // 2
}
Also try it: 100 MongoDB practice problems with solutions
48. Closure as Argument to Custom Function
Write a function apply that takes a closure and a value, and returns the closure applied to the value.
rust
fn apply<F: Fn(i32) -> i32>(f: F, x: i32) -> i32 {
f(x)
}
fn main() {
let square = |n| n * n;
println!("{}", apply(square, 5));
}
49. Threads: Spawn a Basic Thread
Spawn a new thread that prints a message and then join it.
rust
use std::thread;
fn main() {
let handle = thread::spawn(|| {
println!("Hello from thread");
});
handle.join().unwrap();
}
50. Share Data with Arc and Mutex
Count from 1 to 10 using multiple threads, sharing a counter safely.
rust
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
handles.push(thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
}));
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
}
51. Channels: Sending a Message
Create a channel, send a string from one thread, and receive in main.
rust
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(String::from("hello")).unwrap();
});
println!("Received: {}", rx.recv().unwrap());
}
52. Multiple Messages and Iteration
Send multiple numbers and iterate the receiver.
rust
fn main() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
for i in 1..=5 {
tx.send(i).unwrap();
}
});
for received in rx {
println!("Got: {}", received);
}
}
53. Smart Pointer: Box
Use Box to store a recursive data type: a cons list.
rust
enum List {
Cons(i32, Box<List>),
Nil,
}
use List::{Cons, Nil};
fn main() {
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
}
54. Smart Pointer: Deref and Drop
Implement Deref for a custom smart pointer MyBox and observe Drop.
rust
struct MyBox<T>(T);
impl<T> MyBox<T> {
fn new(x: T) -> MyBox<T> { MyBox(x) }
}
impl<T> std::ops::Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &T { &self.0 }
}
impl<T> Drop for MyBox<T> {
fn drop(&mut self) {
println!("Dropping MyBox");
}
}
fn main() {
let x = MyBox::new(5);
println!("{}", *x); // deref
}
55. Reference Counting Rc
Share a resource like String between multiple owners using Rc.
rust
use std::rc::Rc;
fn main() {
let value = Rc::new(String::from("shared"));
let a = Rc::clone(&value);
let b = Rc::clone(&value);
println!("Count: {}", Rc::strong_count(&value)); // 3
}
56. RefCell for Interior Mutability
Mutate data through an immutable reference.
rust
use std::cell::RefCell;
fn main() {
let x = RefCell::new(5);
let y = &x;
*y.borrow_mut() = 10;
println!("{}", x.borrow());
}
57. Combine Rc<RefCell<T>> for Mutable Shared State
rust
use std::rc::Rc;
use std::cell::RefCell;
fn main() {
let data = Rc::new(RefCell::new(0));
let data1 = Rc::clone(&data);
let data2 = Rc::clone(&data);
*data1.borrow_mut() += 1;
*data2.borrow_mut() += 2;
println!("{}", data.borrow()); // 3
}
58. File Reading (with error handling)
Read a file to string and handle potential error.
rust
use std::fs;
fn main() -> Result<(), std::io::Error> {
let content = fs::read_to_string("input.txt")?;
println!("{}", content);
Ok(())
}
59. Write to File
Write a string to a new file.
rust
use std::fs;
fn main() -> Result<(), std::io::Error> {
fs::write("output.txt", "Hello, Rust!")?;
Ok(())
}
60. Environment Variables
Read an environment variable HOME and print it.
rust
use std::env;
fn main() {
match env::var("HOME") {
Ok(path) => println!("Home: {}", path),
Err(e) => println!("Error: {}", e),
}
}
61. Command-Line Arguments
Print all command-line arguments.
rust
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
println!("{:?}", args);
}
62. Parse Integer from CLI Argument
Read first argument, parse to i32, and print double.
rust
use std::env;
fn main() {
if let Some(arg) = env::args().nth(1) {
match arg.parse::<i32>() {
Ok(n) => println!("Double: {}", n * 2),
Err(_) => println!("Not a number"),
}
} else {
println!("No argument");
}
}
63. Recursion: Factorial
Compute factorial using recursion.
rust
fn factorial(n: u64) -> u64 {
match n {
0 => 1,
_ => n * factorial(n - 1),
}
}
fn main() {
println!("5! = {}", factorial(5));
}
64. Recursion: Fibonacci
Return the nth Fibonacci number (recursive, inefficient but simple).
rust
fn fibonacci(n: u32) -> u64 {
if n <= 1 { n as u64 }
else { fibonacci(n - 1) + fibonacci(n - 2) }
}
fn main() {
println!("fib(10) = {}", fibonacci(10));
}
65. Fibonacci with Memoization (HashMap)
Implement Fibonacci using a cache to avoid recomputation.
rust
use std::collections::HashMap;
fn fib_memo(n: u32, cache: &mut HashMap<u32, u64>) -> u64 {
if let Some(&val) = cache.get(&n) { return val; }
let result = match n {
0 => 0,
1 => 1,
_ => fib_memo(n - 1, cache) + fib_memo(n - 2, cache),
};
cache.insert(n, result);
result
}
fn main() {
let mut cache = HashMap::new();
println!("fib(30) = {}", fib_memo(30, &mut cache));
}
66. Bubble Sort
Implement bubble sort for a mutable slice.
rust
fn bubble_sort<T: PartialOrd>(arr: &mut [T]) {
let len = arr.len();
for i in 0..len {
for j in 0..len - i - 1 {
if arr[j] > arr[j + 1] {
arr.swap(j, j + 1);
}
}
}
}
fn main() {
let mut v = [3, 1, 4, 1, 5, 9, 2, 6];
bubble_sort(&mut v);
println!("{:?}", v);
}
67. Selection Sort
rust
fn selection_sort<T: PartialOrd>(arr: &mut [T]) {
let len = arr.len();
for i in 0..len {
let mut min_idx = i;
for j in i + 1..len {
if arr[j] < arr[min_idx] { min_idx = j; }
}
if min_idx != i { arr.swap(i, min_idx); }
}
}
68. Binary Search (Recursive)
rust
fn binary_search<T: Ord>(arr: &[T], target: &T) -> Option<usize> {
if arr.is_empty() { return None; }
let mid = arr.len() / 2;
if &arr[mid] == target { Some(mid) }
else if target < &arr[mid] { binary_search(&arr[..mid], target) }
else { binary_search(&arr[mid+1..], target).map(|idx| mid + 1 + idx) }
}
fn main() {
let v = [1, 3, 5, 7, 9];
println!("{:?}", binary_search(&v, &5));
}
69. Check Palindrome (String)
Case-insensitive, ignore non-alphanumeric.
rust
fn is_palindrome(s: &str) -> bool {
let cleaned: String = s.chars().filter(|c| c.is_alphanumeric()).collect();
cleaned.to_lowercase() == cleaned.chars().rev().collect::<String>().to_lowercase()
}
fn main() {
println!("{}", is_palindrome("A man, a plan, a canal: Panama"));
}
70. Reverse String
rust
fn reverse_string(s: &str) -> String {
s.chars().rev().collect()
}
71. Count Character Occurrences
Count occurrences of each character in a string using a HashMap.
rust
fn char_counts(s: &str) -> HashMap<char, u32> {
let mut map = HashMap::new();
for ch in s.chars() {
*map.entry(ch).or_insert(0) += 1;
}
map
}
72. Find Most Frequent Element in a Vector
rust
fn most_frequent(v: &[i32]) -> Option<i32> {
let mut freq = HashMap::new();
for &val in v {
*freq.entry(val).or_insert(0) += 1;
}
freq.into_iter().max_by_key(|&(_, count)| count).map(|(val, _)| val)
}
73. Remove Duplicates from a Vector
Preserving order using a set.
rust
fn remove_duplicates<T: Eq + Hash + Clone>(v: &[T]) -> Vec<T> {
let mut seen = std::collections::HashSet::new();
let mut res = Vec::new();
for item in v {
if seen.insert(item.clone()) {
res.push(item.clone());
}
}
res
}
74. Merge Two Sorted Vectors
rust
fn merge_sorted(a: &[i32], b: &[i32]) -> Vec<i32> {
let mut res = Vec::with_capacity(a.len() + b.len());
let (mut i, mut j) = (0, 0);
while i < a.len() && j < b.len() {
if a[i] <= b[j] { res.push(a[i]); i += 1; }
else { res.push(b[j]); j += 1; }
}
res.extend_from_slice(&a[i..]);
res.extend_from_slice(&b[j..]);
res
}
75. Generate Prime Numbers up to N (Sieve of Eratosthenes)
rust
fn primes_up_to(n: usize) -> Vec<usize> {
if n < 2 { return vec![]; }
let mut is_prime = vec![true; n + 1];
is_prime[0] = false;
is_prime[1] = false;
for i in 2..=(n as f64).sqrt() as usize {
if is_prime[i] {
for j in (i * i..=n).step_by(i) {
is_prime[j] = false;
}
}
}
is_prime.iter().enumerate().filter(|(_, &p)| p).map(|(i, _)| i).collect()
}
76. Check if a Number is Prime
rust
fn is_prime(n: u64) -> bool {
if n < 2 { return false; }
for i in 2..=(n as f64).sqrt() as u64 {
if n % i == 0 { return false; }
}
true
}
77. GCD (Euclidean Algorithm)
rust
fn gcd(a: u64, b: u64) -> u64 {
if b == 0 { a } else { gcd(b, a % b) }
}
78. LCM
rust
fn lcm(a: u64, b: u64) -> u64 {
a * b / gcd(a, b)
}
79. Convert String to Number with Error Handling
Parse and handle error gracefully using match.
rust
fn parse_i32(s: &str) -> i32 {
s.parse().unwrap_or(0)
}
80. Read CSV Line by Line (Simplified)
Read lines from a hardcoded string and print values.
rust
fn main() {
let data = "name,age\nAlice,30\nBob,25";
for line in data.lines() {
let fields: Vec<&str> = line.split(',').collect();
println!("{:?}", fields);
}
}
81. Simple Unit Test
Write a test for the add function.
rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
}
82. Implement a Counter Struct (Iterator)
Create a struct Counter that counts from start to end and implement Iterator.
rust
struct Counter {
current: i32,
end: i32,
}
impl Counter {
fn new(start: i32, end: i32) -> Counter { Counter { current: start, end } }
}
impl Iterator for Counter {
type Item = i32;
fn next(&mut self) -> Option<Self::Item> {
if self.current <= self.end {
let val = self.current;
self.current += 1;
Some(val)
} else {
None
}
}
}
fn main() {
let c = Counter::new(1, 5);
for i in c { println!("{}", i); }
}
83. Implementing Default Trait
rust
#[derive(Default)]
struct Config {
timeout: u32,
retries: u32,
}
fn main() {
let config = Config { timeout: 30, ..Default::default() };
println!("{}, {}", config.timeout, config.retries);
}
Also try it: 100 Azure practice problems with solutions
84. Implementing From Trait for Type Conversion
Convert a Person into a String.
rust
struct Person { name: String, age: u8 }
impl From<Person> for String {
fn from(p: Person) -> String {
format!("{} ({})", p.name, p.age)
}
}
fn main() {
let p = Person { name: "Alice".into(), age: 30 };
let s: String = p.into();
println!("{}", s);
}
85. ToString and Display
rust
use std::fmt;
impl fmt::Display for Person {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} is {} years old", self.name, self.age)
}
}
86. Implement a Simple Stack Using Vec
rust
struct Stack<T> {
items: Vec<T>,
}
impl<T> Stack<T> {
fn new() -> Self { Stack { items: vec![] } }
fn push(&mut self, item: T) { self.items.push(item); }
fn pop(&mut self) -> Option<T> { self.items.pop() }
fn peek(&self) -> Option<&T> { self.items.last() }
}
87. Implement a Simple Queue Using VecDeque
rust
use std::collections::VecDeque;
struct Queue<T> { data: VecDeque<T> }
impl<T> Queue<T> {
fn new() -> Self { Queue { data: VecDeque::new() } }
fn enqueue(&mut self, item: T) { self.data.push_back(item); }
fn dequeue(&mut self) -> Option<T> { self.data.pop_front() }
fn len(&self) -> usize { self.data.len() }
}
88. Split a String into Words and Count Unique
rust
fn unique_words(text: &str) -> usize {
let set: std::collections::HashSet<_> = text.split_whitespace().collect();
set.len()
}
89. FizzBuzz (1 to 100)
rust
fn main() {
for i in 1..=100 {
if i % 15 == 0 { println!("FizzBuzz"); }
else if i % 3 == 0 { println!("Fizz"); }
else if i % 5 == 0 { println!("Buzz"); }
else { println!("{}", i); }
}
}
90. Sum of Digits
rust
fn sum_of_digits(mut n: u32) -> u32 {
let mut sum = 0;
while n > 0 { sum += n % 10; n /= 10; }
sum
}
91. Factorial Using fold (1..=n)
rust
fn factorial_fold(n: u32) -> u32 {
(1..=n).fold(1, |acc, x| acc * x)
}
92. Find Duplicate Elements in a Vector
rust
fn find_duplicates<T: Eq + Hash + Clone>(v: &[T]) -> Vec<T> {
let mut seen = HashSet::new();
let mut duplicates = Vec::new();
for item in v {
if !seen.insert(item.clone()) {
duplicates.push(item.clone());
}
}
duplicates
}
93. Rotate a Vector Right by K
rust
fn rotate_right(v: &[i32], k: usize) -> Vec<i32> {
let len = v.len();
if len == 0 { return v.to_vec(); }
let k = k % len;
[&v[len - k..], &v[..len - k]].concat()
}
94. Transpose a 2D Matrix (Square)
rust
fn transpose(matrix: &Vec<Vec<i32>>) -> Vec<Vec<i32>> {
let n = matrix.len();
let mut result = vec![vec![0; n]; n];
for i in 0..n {
for j in 0..n {
result[j][i] = matrix[i][j];
}
}
result
}
95. Check if a String Contains All Unique Characters
rust
fn all_unique(s: &str) -> bool {
let mut seen = HashSet::new();
for ch in s.chars() {
if !seen.insert(ch) { return false; }
}
true
}
96. CamelCase to snake_case Conversion
rust
fn camel_to_snake(s: &str) -> String {
let mut out = String::new();
for (i, ch) in s.chars().enumerate() {
if ch.is_uppercase() {
if i != 0 { out.push('_'); }
out.push(ch.to_ascii_lowercase());
} else {
out.push(ch);
}
}
out
}
97. Generate Random Number Between 1 and 10
rust
use rand::Rng;
fn main() {
let num = rand::thread_rng().gen_range(1..=10);
println!("{}", num);
}
98. Time a Function Execution
Measure elapsed time for a function call.
rust
use std::time::Instant;
fn main() {
let start = Instant::now();
// some computation
let duration = start.elapsed();
println!("Time: {:?}", duration);
}
99. Simple Configuration Struct with Builder Pattern
rust
#[derive(Debug, Default)]
struct ConfigBuilder {
timeout: Option<u32>,
retries: Option<u32>,
}
impl ConfigBuilder {
fn timeout(mut self, val: u32) -> Self { self.timeout = Some(val); self }
fn retries(mut self, val: u32) -> Self { self.retries = Some(val); self }
fn build(self) -> Config2 {
Config2 {
timeout: self.timeout.unwrap_or(30),
retries: self.retries.unwrap_or(3),
}
}
}
struct Config2 { timeout: u32, retries: u32 }
fn main() {
let config = ConfigBuilder::default().timeout(60).build();
println!("{:?}", (config.timeout, config.retries));
}
100. Simple HTTP GET Request (using reqwest blocking)
Fetch the content of a URL and print the length.
rust
// Cargo.toml: reqwest = { version = "0.11", features = ["blocking"] }
use reqwest;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let body = reqwest::blocking::get("https://www.rust-lang.org")?.text()?;
println!("Length: {}", body.len());
Ok(())
}
100 Dart practice problems with solutions
Conclusion: Forged Stronger with Rust
Completing these 100 Rust practice problems with solutions is not just about writing code—it’s about building patience, discipline, and confidence. Rust is known for challenging developers, and every problem you solved proves that you didn’t give up when things got tough.
There were moments when errors felt confusing and solutions seemed far away, but each struggle taught you something valuable. Every fix, every success, and every lesson learned made you stronger as a programmer.
Remember, mastering Rust is like forging steel—it takes time, pressure, and persistence. Keep going, trust your progress, and never doubt your ability to grow. This is not the end of your Rust journey—it’s the moment where your real confidence begins.