Weekly Rust Trivia is a problem-oriented series of articles that assist developers while learning Rust. Every article solves simple, everyday development tasks using the Rust standard library or leveraging popular and proven crates.
Question: How to implement a generic stack in Rust?
To implement a generic stack, we can simply create a custom struct wrapping a vector (Vec<T>
):
struct Stack<T> {
items: Vec<T>,
}
impl<T> Stack<T> {
fn new() -> Stack<T> {
Stack { items: Vec::new() }
}
fn push(&mut self, item: T) {
self.items.push(item);
}
fn pop(&mut self) -> Option<T> {
self.items.pop()
}
fn is_empty(&self) -> bool {
self.items.is_empty()
}
fn size(&self) -> usize {
self.items.len()
}
}
The implementation (impl<T> Stack<T>
) uses a generic type T
to allow it to store any type of data. The Stack
struct has four methods: new
, push
, pop
, is_empty
, and size
:
- The
new
method creates a new instance of theStack
struct by creating a new empty vector (Vec<T>
) - The
push
method adds a new item to the top of the stack by pushing it onto the vector - The
pop
method removes and returns the top item from the stack, or returnsNone
if the stack is empty - The
is_empty
method returns a boolean value indicating whether or not the stack is empty - The
size
method returns the number of items currently in the stack
This implementation provides a basic functionality for a stack, which can be used to store and manipulate data in a Last-In-First-Out (LIFO) manner. The following code demonstrate using the generic stack with values of type i32
:
fn main() {
let mut stack = Stack::new();
println!("Pushing 1");
stack.push(1);
println!("Pushing 2");
stack.push(2);
println!("Pushing 3");
stack.push(3);
println!("Size of the Stack: {}", stack.size());
let first = stack.pop();
println!("Got: {:?}", first);
let second = stack.pop();
println!("Got: {:?}", second);
println!("Pushing 4");
stack.push(4);
let third = stack.pop();
println!("Got: {:?}", third);
let fourth = stack.pop();
println!("Got: {:?}", fourth);
let fifth = stack.pop();
println!("Got: {:?}", fifth);
println!("Is the stack empty? {}", stack.is_empty());
}
When we execute the program, the following output will be generated:
Pushing 1
Pushing 2
Pushing 3
Size of the Stack: 3
Got: Some(3)
Got: Some(2)
Pushing 4
Got: Some(4)
Got: Some(1)
Got: None
Is the stack empty? true