Introduction to Structs: Creating Custom Data Types
Welcome to Chapter 2! We've built a solid foundation with Rust's basic data types, collections, and control flow. Now, we're going to start exploring some of Rust's more powerful features that allow you to create complex and expressive programs.
We'll begin with structs. A struct, or structure, is a custom data type that lets you package together and name multiple related values that make up a meaningful group.
π Prerequisitesβ
Before we begin, you should be familiar with:
- Basic data types (integers, strings, etc.).
- The concept of ownership.
π― Article Outline: What You'll Masterβ
In this article, you will learn:
- β What a struct is and why it's useful.
- β How to define a struct.
- β How to create an instance of a struct.
- β How to access and modify the data in a struct.
π§ Section 1: What is a Struct?β
Think of a struct like a template for creating a custom data type. If you're building an application that involves users, you might want to store a user's email, username, and sign-in count all together. A struct allows you to group these related pieces of data into a single, cohesive unit called User.
This is different from a tuple, where the elements are unnamed. With a struct, you give each piece of data a name, so it's clear what the values mean.
π» Section 2: Defining and Instantiating a Structβ
To define a struct, you use the struct keyword followed by the name of the struct and a block of curly braces containing the names and types of its fields.
struct User {
active: bool,
username: String,
email: String,
sign_in_count: u64,
}
To create an instance of a struct, you specify the struct's name and then provide concrete values for each field in key: value pairs.
fn main() {
let user1 = User {
email: String::from("[email protected]"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
}
π¬ Section 3: Accessing and Modifying Struct Dataβ
You can access the data in a struct instance using dot notation.
fn main() {
let user1 = User {
email: String::from("[email protected]"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
println!("Username: {}", user1.username);
}
To modify a struct's data, the instance must be mutable. The entire instance must be mutable; Rust doesnβt allow us to mark only certain fields as mutable.
fn main() {
let mut user1 = User {
email: String::from("[email protected]"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
user1.email = String::from("[email protected]");
}
π οΈ Section 4: Struct Update Syntaxβ
It's often useful to create a new instance of a struct that uses most of an old instanceβs values but changes some. You can do this with the struct update syntax.
fn main() {
let user1 = User {
email: String::from("[email protected]"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
// Create a new User instance that is mostly the same as user1
let user2 = User {
email: String::from("[email protected]"),
..user1 // The `..` syntax specifies that the remaining fields
// not explicitly set should have the same value as the
// fields in user1.
};
}
Important Note on Ownership: In this example, we can no longer use user1 as a whole after creating user2 because the String in the username field of user1 was moved into user2.
β¨ Conclusion & Key Takeawaysβ
Structs are a fundamental building block for creating custom types in Rust. They allow you to organize your data in a meaningful way, which makes your code easier to read, understand, and maintain.
Let's summarize the key takeaways:
- A
structis a custom data type that groups related values. - Define a struct with the
structkeyword and named fields. - Create an instance by specifying the struct name and values for the fields.
- Access data with dot notation.
- The entire instance must be mutable to modify its fields.
Challenge Yourself:
Define a Car struct with fields for make (a String), model (a String), and year (a u32). Create an instance of your Car struct and print out its details.
β‘οΈ Next Stepsβ
You've learned the basics of defining and using structs. In the next article, "Tuple Structs and Unit-Like Structs", we will explore two other variations of structs that can be useful in different situations.
You're now able to create your own custom data types. This is a huge step towards writing more complex and expressive Rust programs!