Masai Mahapa

30 days of Rust - Day Sixteen - Smart Pointers

30 days of rust - day Sixteen

Day 16 - Smart Pointers

Today's concept is by far the most advanced topic I have covered in Rust. It took me quite a long time to even get a bit of an understanding of what pointers are and why we even need them.

What are pointers

Pointers are basically variables that hold an address to an object in memory. In Rust the most common kind of pointer is the Reference, which we often see represented with the & symbol. They do nothing but refer/point to data.

What are smart pointers?

Smart pointers on the other hand are data structures which are similar to pointers with additional metadata and features. They can be the owners of data unlike normal references that just borrow. One of these additional capabilities is reference counting, which is a way of keeping track of how many owners there are to a piece of data. Once there are no more owners, the piece of data can be dropped/ removed from memory.

Smart Pointers in the standard library

1. Box<T>

Allows us to store values on the heap, instead of stack.

The heap is a general term that describes boxes, but in this case is used to store data of an unknown size or a size that might change.

They are most useful in cases where we cannot determine the size of a type at compile time. The rust compiler wants to know how much space to allocate, which may be a problem when working with recursion.

This is where we can use the Box<T> type so that the compiler can know how much memory to allocate.

Think about how you'd create a linked list. So basically, a linked list is a data structure made up of Nodes which contain a value and the address of the next value.

linked list

A similar data structure, called the Cons list. To represent 1,2,3 we'd have something which looks like this.

(1, (2, (3, Nil)))

Each item in the list has 2 items, being the value and another Cons list. Until the last item which has the value and Nil to represent that there's no next element.

To have this in rust, be an enum that looks like;

enum List {
   Cons(i32, List),
   Nil,
}

The code above does not run. The reason is because List is of an unknown size. Rust will not compile code until it knows what size it is.

cons infinite

To solve this, we can use the Box pointer, because a pointer will always be of a fixed size. The same way the address of your apartment is of the same size as that of the shopping mall. Since all it does it point to an object on the heap.

enum List {
   Cons(i32, Box<List>),
   Nil,
}
 
use crate::List::{Cons, Nil};
 
fn main() {
   let list = Cons(1, Box::new(
       Cons(2, Box::new(
       Cons(3, Box::new(Nil))))));
}

cons finite

Thanks to the Box, we now have a finite List because Cons can hold a Box.

Conclusion

This is enough smart pointers for today. The learning curve is only getting steeper. Now I can even speak with my Computer Science friends at dinner parties about pointers and sound smart too.

Tomorrow I will cover the rest on smart pointers.

Thanks for spending some time learning Rust with me. Until next time. Peace ✌🏼 .

Share