Rust

Rust structs and enums: a hands-on approach

Rust structs and enums: a hands-on approach

As a Rust enthusiast, I can't help but be fascinated by how the language offers both power and safety in equal measures. Today, I want to share my personal experience with you as we explore two essential concepts in Rust: structs and enums. By the end of this article, you'll not only understand how to define and use structs, but also how to implement methods and work with enums through pattern matching. Let's dive in!

Defining and using structs

Structs, short for structures, are the building blocks of Rust. They are custom data types that allow you to group related data together. Let's see how to define a struct and use it in a real-world scenario.

Imagine you're building a simple application to track the reading progress of your favorite books. You might want to define a Book struct as follows:

struct Book {
  title: String,
  author: String,
  pages: u32,
  current_page: u32,
}

To create an instance of the Book struct, you can use the following syntax:

let my_book = Book {
  title: String::from("Rust for Rustaceans"),
  author: String::from("Jon Gjengset"),
  pages: 350,
  current_page: 42,
};

You can access the fields of a struct using the dot notation:

println!("Currently reading {} by {}.", my_book.title, my_book.author);

Implementing methods for structs

Structs become even more powerful when you implement methods for them. Let's add a method to update the current_page field in our Book struct:

impl Book {
  fn update_current_page(&mut self, new_page: u32) {
    self.current_page = new_page;
  }
}

Now, you can easily update the current_page field using the new method:

my_book.update_current_page(85);
println!("I'm now on page {} of {}.", my_book.current_page, my_book.title);

Introduction to enums and pattern matching

Enums, short for enumerations, are another powerful feature in Rust. They allow you to define a type that represents a choice between different options or variants. Enums are perfect for situations where a value can be one of several possibilities.

Let's say you want to track the status of a book. You can create an enum to represent the various states:

enum BookStatus {
  NotStarted,
  Reading { current_page: u32 },
  Completed,
}

We can now add a status field to our Book struct:

struct Book {
  title: String,
  author: String,
  pages: u32,
  status: BookStatus,
}

Pattern matching is a powerful technique in Rust that allows you to handle the different variants of an enum. Here's how you can implement a method to display the status of a book:

impl Book {
  fn display_status(&self) {
    match &self.status {
      BookStatus::NotStarted => println!("{} is not started yet.", self.title),
      BookStatus::Reading { current_page } => println!("{} is being read. Currently on page {}.", self.title, current_page),
      BookStatus::Completed => println!("{} has been completed.", self.title),
    }
  }
}

With this, you can now create instances of the Book struct with different statuses and display their statuses using the display_status method:

let book1 = Book {
  title: String::from("Rust for Rustaceans"),
  author: String::from("Jon Gjengset"),
  pages: 350,
  status: BookStatus::NotStarted,
};

let book2 = Book {
  title: String::from("The Rust Programming Language"),
  author: String::from("Steve Klabnik & Carol Nichols"),
  pages: 520,
  status: BookStatus::Reading { current_page: 120 },
};

let book3 = Book {
  title: String::from("Rust in Action"),
  author: String::from("Tim McNamara"),
  pages: 400,
  status: BookStatus::Completed,
};

book1.display_status();
book2.display_status();
book3.display_status();

This would output:

Rust for Rustaceans is not started yet.
The Rust Programming Language is being read. Currently on page 120.
Rust in Action has been completed.

Wrapping up

In this article, we explored the power of Rust structs and enums through real-world examples. We learned how to define and use structs, implement methods for them, work with enums, and use pattern matching. This should give you a solid foundation to build more complex applications with Rust.

Rust's safety and expressiveness make it an excellent choice for modern software development. As you continue learning, you'll discover more exciting features that make Rust even more enjoyable to work with.

Happy coding, Rustaceans!

A blog for self-taught engineers

Сommunity is filled with like-minded individuals who are passionate about learning and growing as engineers.