Defining and Using Structs
Create custom data structures with structs, including tuple structs and unit-like structs, to group related data.
Defining and Using Structs is a free Learn Rust Coding lesson on CoddyKit — lesson 1 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Meet Structs: Custom Data Types
In Rust, structs (short for structures) are a way to create custom data types that let you name and package together multiple related values into a meaningful group.
Think of a struct as a blueprint for a user, a color, or a point in space. Instead of having separate variables for a user's name, email, and age, you can put them all inside a User struct.
This helps you organize your data logically and make your code easier to read and maintain.
Defining a Classic Struct
The most common type of struct is a classic struct, where you name each piece of data, called a field. Here's how you define one:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
// This code only defines the struct blueprint.
// No actual user has been created yet!
println!("Struct 'User' blueprint defined.");
}Creating Struct Instances
Once you define a struct, you can create concrete instances of it. Each instance holds specific values for its fields. You create an instance by specifying concrete values for each field.
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
email: String::from("alice@example.com"),
username: String::from("alice123"),
active: true,
sign_in_count: 1,
};
println!("User instance created!");
}Accessing Struct Fields
To get data out of a struct instance, you use dot notation. Simply type the instance name, a dot (.), and then the field name.
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
email: String::from("alice@example.com"),
username: String::from("alice123"),
active: true,
sign_in_count: 1,
};
println!("User's username: {}", user1.username);
println!("User's email: {}", user1.email);
}Mutability with Structs
Just like regular variables, entire struct instances can be made mutable using the mut keyword. If an instance is mutable, all of its fields can be changed.
You cannot make only certain fields mutable; the mutability applies to the struct instance as a whole.
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let mut user1 = User {
email: String::from("alice@example.com"),
username: String::from("alice123"),
active: true,
sign_in_count: 1,
};
println!("Old email: {}", user1.email);
user1.email = String::from("new_alice@example.com");
println!("New email: {}", user1.email);
}Tuple Structs: Unnamed Fields
Tuple structs are another form of struct that look like tuples but have a name. They're useful when you want to give a tuple a distinct type name, but don't need to name its individual fields.
For example, Color(i32, i32, i32) is a named tuple that groups three integers together.
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
println!("Tuple structs 'Color' and 'Point' defined.");
}Using Tuple Structs
Creating an instance of a tuple struct is similar to creating a regular tuple. To access the values inside, you use dot notation with their index, starting from 0.
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
println!("Black color: R={}, G={}, B={}", black.0, black.1, black.2);
println!("Origin point: X={}, Y={}, Z={}", origin.0, origin.1, origin.2);
}Unit-Like Structs: Markers
You can also define structs that have no fields at all. These are called unit-like structs because they behave similarly to the unit type ().
They are often used as markers to implement a particular trait on a type, where the data itself is not important.
struct AlwaysTrue;
fn main() {
let subject = AlwaysTrue;
// Unit-like structs don't store data directly,
// but they can be instantiated and used as types.
println!("Unit-like struct 'AlwaysTrue' created.");
}Struct Update Syntax
If you need to create a new struct instance based on an existing one, but only want to change some field values, Rust offers a convenient struct update syntax (..).
This syntax moves the remaining fields from the specified instance, so the original instance can no longer be used if it contains fields that implement Copy.
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
email: String::from("alice@example.com"),
username: String::from("alice123"),
active: true,
sign_in_count: 1,
};
let user2 = User {
email: String::from("bob@example.com"),
username: String::from("bob456"),
..user1 // Copy remaining fields from user1
};
println!("User 2 email: {}", user2.email);
println!("User 2 active: {}", user2.active);
// user1.username is now moved, so user1 can't be used here.
}Structs Quiz
Test your understanding of Rust structs.
Recap: Structs Overview
You've learned how to define and use structs in Rust!
- Classic structs group named fields to create custom data types.
- Tuple structs are named tuples, useful when field names aren't strictly necessary.
- Unit-like structs have no fields and act as markers.
- Struct instances can be made
mutto allow modification of their fields. - The
..syntax helps create new instances from existing ones.
Structs are fundamental for organizing related data in Rust programs, making your code more structured and readable.
Frequently asked questions
Is the “Defining and Using Structs” lesson free?
Yes — the full text of “Defining and Using Structs” is free to read here on the web, and the Learn Rust Coding course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.
What will I learn in “Defining and Using Structs”?
Create custom data structures with structs, including tuple structs and unit-like structs, to group related data. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Learn Rust Coding?
No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 3, so you can start here or from the beginning and move at your own pace.
How long does the “Defining and Using Structs” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Learn Rust Coding lesson?
Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Defining and Using Structs
- Enums for Custom Types
- Powerful Pattern Matching