Rust’s Magic Box

Rust’s Magic Box

Cooked up exercises to really get into the guts of how Box ticks

  • Basic Box Allocation: Create a Box that contains a single i32 value. Print the value to confirm it's correctly allocated.

  • Box and Functions: Write a function that takes a Box<i32> and returns the value inside multiplied by 10. Ensure you understand ownership transfer with Box.

  • Recursive Data Structures: Implement a basic singly linked list using Box. Define enum List that can either be a node with an integer and a pointer to another List, or it can be Nil.

  • Dynamic Array with Boxes: Create a vector of Box<i32>. Initialize this vector with at least five integers, manipulate them, and print the results.

  • Boxing in a Struct: Define a struct that contains a Box holding another struct. Initialize and print the nested structure to see how Box works with user-defined types.

  • Clone with Box: Implement a function that clones a Box<i32> without using the standard cloning mechanism. Hint: manually create a new Box with the same value.

  • Memory Comparison: Compare the stack memory usage of a regular i32 to the heap memory usage of a Box<i32>. You can use Rust's std::mem::size_of_val function to measure this.

  • Box Slice: Create a Box<[i32]> directly from a boxed slice allocation (Box::new([1, 2, 3, 4, 5])). Manipulate and print the slice.

  • Box and Trait Objects: Define a trait Animal with a method speak. Implement this trait for two structs, Dog and Cat. Use Box<dyn Animal> to store instances of these structs in a vector and iterate through the vector, calling speak on each animal.

  • Complex Data Structures: Implement a binary tree where each node contains an integer and two children, left and right, both of which are Option<Box<Node>>. Add methods to insert values and print the tree in order.

  • Box a Tuple: Create a Box containing a tuple with multiple types of data (e.g., i32, f64, String). Access and print each element of the tuple.

  • Custom Smart Pointer: Implement a simple smart pointer using Box. This should encapsulate a basic resource (like an integer or string), and handle automatic resource deallocation.

  • Box and Mutability: Explore mutability with Box by creating a Box<i32>, then change the value inside the Box without creating a new Box.

  • Box in Conditional Statements:Use a Box to store a value based on a conditional statement (e.g., if-else). The value type should be consistent, but the value itself should vary based on the condition.

  • Implement Drop for Boxed Type: Create a struct that contains a Box of some data, and implement the Drop trait to print a message when an instance of the struct is dropped.

  • Box and Closures: Store a closure inside a Box. The closure should take an integer and return its square. Call this closure through the Box.

  • Transfer of Ownership in Threads: Use Box to transfer ownership of a large data structure (like a vector) to a new thread, modify it inside the thread, and then print the modified data after joining the thread.

  • Boxing Errors: Implement error handling where you return a Result containing either a Box<dyn Error> on failure or a usize on success. Trigger both outcomes to see how Rust handles boxed errors.

  • Nested Boxes: Create multiple nested Box layers (e.g., Box<Box<Box<i32>>>) and manipulate the innermost value. Explore how Rust manages memory and ownership through multiple layers of indirection.

  • Box with Enums and Matching: Define an enum with different variants, some of which contain boxed values. Create instances of these variants and use pattern matching to perform different actions based on the variant and the boxed values.