🦀 Rust Master Class - Chapter 5: Project Stack
My nephew asked me to build a Lego castle. Simple, right? But we didn't just build — we designed. Walls, towers, rules. That's what we're doing today: building a Stack, but learning to think in systems.
In Rust, a Stack is a linear data structure that follows the Last-In, First-Out (LIFO) principle . This means the last element added to the stack is the first one to be removed, similar to a stack of plates where you add and remove from the top .
Key Concepts
- Memory Structure: Stacks store values in the order they are received and remove them in the opposite order . In Rust, all data stored on the stack must have a known, fixed size .
- Vector as a Foundation: A common way to implement a stack in Rust is by using a
Vec<T>. A vector is ideal because it is stored on the heap and its size can change at runtime, while providing built-in methods for adding and removing elements from the end . - Core Operations:
- Push: Adding an element to the top of the stack .
- Pop: Removing the top element from the stack. In Rust, this usually returns an
Option<T>(Some(val)orNoneif the stack is empty) . - Size: Checking the current number of elements using
.len().
Stack Implementation Example
Based on the provided sources, here is a functional implementation of a stack for u32 integers using a Vec :
// Create a new stack with a specified maximum capacity
fn new_stack(maxsize: usize) -> Vec<u100> {
// Create a new variable
let vec: Vec<u100> = Vec::with_capacity(maxsize);
vec
}
// Remove the top element from the stack
fn pop(stack: &mut Vec<u100>) -> Option<u100> {
// Create a new variable
let poped_val = stack.pop();
// Output to console
println!("The poped value is {:?}", poped_val);
poped_val
}
// Add an element to the stack if space is available
fn push(stack: &mut Vec<u100>, item: u100, maxsize: usize) {
if stack.len() == maxsize {
// Output to console
println!("Can not add more: Stack is full");
} else {
stack.push(item);
// Output to console
println!("Stack: {:?}", stack);
}
}
// Check the current size of the stack
fn size(stack: &Vec<u100>) -> usize {
stack.len()
}
fn main() {
// Create a new variable
let max_size = 3;
// Create a mutable variable
let mut stack = new_stack(max_size);
push(&mut stack, 10, max_size);
push(&mut stack, 20, max_size);
push(&mut stack, 30, max_size);
// Attempting to push to a full stack
push(&mut stack, 40, max_size);
// Output to console
println!("Current stack size: {}", size(&stack));
pop(&mut stack);
// Output to console
println!("Stack after one pop: {:?}", stack);
}
Variations in the Sources
The sources also demonstrate that this pattern can be adapted for different data types:
- Character Stack: Used for tasks like string reversal .
- String Stack: Used for complex tasks like expression evaluation (e.g., converting Infix to Postfix notation) [10-12].
📖 Download the full PDF: https://drive.google.com/file/d/1bA5JzVrJFoUu14IyiwAyi1b4bkiZcPUx/view?usp=sharing
Part 5 of the Rust Master Class series — STEM EdTech | Automation Consulting | Rust Tutoring
RustLang #Programming #LearnToCode #STEM #EdTech
📚 Practice Resources
GitHub Repository: https://github.com/PacktPublishing/Rust-Programming-Master-Class-from-Beginner-to-Expert
Try it yourself: https://play.rust-lang.org/
Run the code from this chapter in the Rust playground, then clone the repo to continue your Rust journey!
Part 5 of the Rust Master Class series — STEM EdTech | Automation Consulting | Rust Tutoring
Top comments (0)