We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Generics and Traits step 5 of 24
Build a generic stack with conditional methods
Complete a stack that can store any element type. Its basic operations
should need no trait bounds; only its text-rendering method requires
Display.
pub struct Stack<T> {
items: Vec<T>,
}
Keep the supplied new, push, pop and len methods. Add:
pub fn is_empty(&self) -> boolfor everyT.DefaultforStack<T>for everyT, producing an empty stack.pub fn render(&self) -> Stringin animpl<T: Display> Stack<T>block. Join the elements' display text from bottom to top with commas, without brackets or extra spaces. For an empty stack, return an empty string.
Then complete the command interpreter:
pub fn run(ops: Vec<(String, i64)>) -> Vec<String>
run starts with an empty Stack<i64> and returns one string per operation.
Only push uses the numeric argument; every other operation ignores it.
| Operation | Effect | Output |
|---|---|---|
push |
Push the argument onto the top. | len=<new length> |
pop |
Remove the top value, if present. | pop=<value> or pop=none |
render |
Read the stack without changing it. | The result of render wrapped in [ and ] |
empty |
Read whether the stack is empty. | empty=true or empty=false |
| Any other name | Leave the stack unchanged. | ? |
Operation names are case-sensitive. Values span the full i64 range. An
empty operation list returns an empty vector, and popping an empty stack
must not panic.
For example:
operations: [("push", 5), ("push", -3), ("render", 0), ("pop", 0), ("render", 0)]
output: ["len=1", "len=2", "[5,-3]", "pop=-3", "[5]"]
Separate the methods by their requirements
In impl<T> Stack<T>, the first <T> declares the block's type parameter.
Stack<T> then uses that parameter. Methods in this block work for any
element type, including types that implement neither Default nor Display.
In impl<T: Display> Stack<T>, the bound makes render available when
elements implement Display. Keep the bound on this block rather than
placing it on the struct or all its methods. Storing a value does not require
knowing how to print it.
Stack<i64> and Stack<String> are distinct types. They share the generic
definition, but you cannot assign one to a variable of the other type.
An impl Stack<i64> block would add methods only for integer stacks, so it
would not meet the generic requirements here.
Default without an element bound
Write Default manually and delegate to Self::new(). An empty vector
contains no elements, so constructing it does not need a default value of T.
For this struct, #[derive(Default)] adds a T: Default bound. That would
unnecessarily prevent callers from using Stack::<NotDefault>::default().
The manual implementation should use impl<T> Default for Stack<T> with
no bound on T.
Completing the starter
The starter has working storage methods, but run handles only push.
It also imports Display before using it. Add the missing operations and
conditional rendering method, then provide Default and is_empty.
The Clippy gate checks this public API with new_without_default and
len_without_is_empty. These checks encourage familiar method pairs;
they do not verify stack order or whether your generic bounds are minimal.
Check those requirements too, including a stack of a type without
Default or Display.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.