From 61c7eaed6251fb8a28b00ea97b22d1f1b778a72b Mon Sep 17 00:00:00 2001 From: mo8it Date: Fri, 28 Jun 2024 21:24:35 +0200 Subject: [PATCH] box1 solution --- exercises/19_smart_pointers/box1.rs | 30 +++++++++--------- rustlings-macros/info.toml | 15 +++------ solutions/19_smart_pointers/box1.rs | 48 ++++++++++++++++++++++++++++- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/exercises/19_smart_pointers/box1.rs b/exercises/19_smart_pointers/box1.rs index c8c2640..d70e1c3 100644 --- a/exercises/19_smart_pointers/box1.rs +++ b/exercises/19_smart_pointers/box1.rs @@ -4,45 +4,43 @@ // `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 +// 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 +// 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 +// TODO: Use a `Box` in the enum definition to make the code compile. #[derive(PartialEq, Debug)] 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() - ); -} - +// TODO: Create an empty cons list. fn create_empty_list() -> List { todo!() } +// TODO: Create a non-empty cons list. fn create_non_empty_list() -> List { todo!() } +fn main() { + println!("This is an empty cons list: {:?}", create_empty_list()); + println!( + "This is a non-empty cons list: {:?}", + create_non_empty_list(), + ); +} + #[cfg(test)] mod tests { use super::*; #[test] fn test_create_empty_list() { - assert_eq!(List::Nil, create_empty_list()); + assert_eq!(create_empty_list(), List::Nil); } #[test] diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml index 72f956b..744ad08 100644 --- a/rustlings-macros/info.toml +++ b/rustlings-macros/info.toml @@ -969,21 +969,16 @@ a different method that could make your code more compact than using `fold`.""" name = "box1" dir = "19_smart_pointers" hint = """ -Step 1: - -The compiler's message should help: since we cannot store the value of the +The compiler's message should help: Since we cannot store the value of the actual type when working with recursive types, we need to store a reference (pointer) to its value. -We should, therefore, place our `List` inside a `Box`. More details in the book -here: https://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes +We should, therefore, place our `List` inside a `Box`. More details in The Book: +https://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes -Step 2: +Creating an empty list should be fairly straightforward (Hint: Read the tests). -Creating an empty list should be fairly straightforward (hint: peek at the -assertions). - -For a non-empty list keep in mind that we want to use our `Cons` "list builder". +For a non-empty list, keep in mind that we want to use our `Cons` list builder. Although the current list is one of integers (`i32`), feel free to change the definition and try other types!""" diff --git a/solutions/19_smart_pointers/box1.rs b/solutions/19_smart_pointers/box1.rs index 4e18198..189cc56 100644 --- a/solutions/19_smart_pointers/box1.rs +++ b/solutions/19_smart_pointers/box1.rs @@ -1 +1,47 @@ -// Solutions will be available before the stable release. Thank you for testing the beta version 🥰 +// 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`. + +#[derive(PartialEq, Debug)] +enum List { + Cons(i32, Box), + Nil, +} + +fn create_empty_list() -> List { + List::Nil +} + +fn create_non_empty_list() -> List { + List::Cons(42, Box::new(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(), + ); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_create_empty_list() { + assert_eq!(create_empty_list(), List::Nil); + } + + #[test] + fn test_create_non_empty_list() { + assert_ne!(create_empty_list(), create_non_empty_list()); + } +}