Rustlings: box1.rs #Issue81 — Smart Pointers in Rust
Rustlings Challenge: box1.rs Solution Walkthrough

This is the Eighty-first (81st) issue of the Rustlings series. In this issue, we provide solutions to Rustlings exercises along with detailed explanations. In this issue we will solve the challenge on box1.rs.
Previous challenge #Issue 80
In Rust, smart pointers are variables that contain an address in memory and reference some other data, but they also have additional metadata and capabilities. Smart pointers in Rust often own the data they point to, while references only borrow data.
Challenge
// box1.rs
//
// At compile time, Rust needs to know how much space a type takes up. This
// becomes problematic for recursive types, where a value can have as part of
// itself another value of the same type. To get around the issue, we can use a
// `Box` - a smart pointer used to store data on the heap, which also allows us
// to wrap a recursive type.
//
// The recursive type we're implementing in this exercise is the `cons list` - a
// data structure frequently found in functional programming languages. Each
// item in a cons list contains two elements: the value of the current item and
// the next item. The last item is a value called `Nil`.
//
// Step 1: use a `Box` in the enum definition to make the code compile
// Step 2: create both empty and non-empty cons lists by replacing `todo!()`
//
// Note: the tests should not be changed
//
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
// I AM NOT DONE
#[derive(PartialEq, Debug)]
pub enum List {
Cons(i32, List),
Nil,
}
fn main() {
println!("This is an empty cons list: {:?}", create_empty_list());
println!(
"This is a non-empty cons list: {:?}",
create_non_empty_list()
);
}
pub fn create_empty_list() -> List {
todo!()
}
pub fn create_non_empty_list() -> List {
todo!()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_empty_list() {
assert_eq!(List::Nil, create_empty_list())
}
#[test]
fn test_create_non_empty_list() {
assert_ne!(create_empty_list(), create_non_empty_list())
}
}Explanation
Use Box Smart Pointer in Enum Definition:
Change the List enum definition to use the Box smart pointer for the recursive variant:
#[derive(PartialEq, Debug)]
pub enum List {
Cons(i32, Box<List>), // Use Box smart pointer
Nil,
}Implement create_empty_list Function:
Implement the create_empty_list function to create an empty cons list represented by the Nil variant:
pub fn create_empty_list() -> List {
List::Nil
}Implement create_non_empty_list Function:
Implement the create_non_empty_list function to create a non-empty cons list with some sample values (e.g., 1, 2, 3):
pub fn create_non_empty_list() -> List {
let list = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
list
}Solution
#[derive(PartialEq, Debug)]
pub enum List {
Cons(i32, Box<List>),
Nil,
}
fn main() {
println!("This is an empty cons list: {:?}", create_empty_list());
println!(
"This is a non-empty cons list: {:?}",
create_non_empty_list()
);
}
pub fn create_empty_list() -> List {
List::Nil
}
pub fn create_non_empty_list() -> List {
let list = List::Cons(1, Box::new(List::Cons(2, Box::new(List::Cons(3, Box::new(List::Nil))))));
list
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_empty_list() {
assert_eq!(List::Nil, create_empty_list())
}
#[test]
fn test_create_non_empty_list() {
assert_ne!(create_empty_list(), create_non_empty_list())
}
}You can experiment with the code on Rust Playground.
Resources
- Smart Pointers
- Using Box to Point to Data on the Heap
- Rc
, the Reference Counted Smart Pointer - Shared-State Concurrency
- Cow Documentation
Before you go
Thank you for taking the time to read through this challenge. We invite you to share your knowledge of Rust as well. If you found this article valuable, please don’t hesitate to share it with others. Don’t forget to follow the publication and give the article some claps 👏.
Thank you, and we look forward to seeing you for the next challenges!





