Rust Structs
A struct groups related values into one named type. Where a tuple is a quick, unnamed bundle, a struct gives every field a name — which makes the code that uses it far easier to read.
Defining and creating a struct
Section titled “Defining and creating a struct”struct Person { name: String, age: u32,}
fn main() { let alice = Person { name: String::from("Alice"), age: 30, };
println!("{} is {}", alice.name, alice.age);}Output:
Alice is 30Compare this to a tuple ("Alice", 30) — with a struct, alice.name and alice.age are self-explanatory. You don’t have to remember that field 0 is the name and field 1 is the age.
Making a struct mutable
Section titled “Making a struct mutable”Like variables, struct instances are immutable by default. Add mut to change a field after creating it:
struct Person { name: String, age: u32,}
fn main() { let mut alice = Person { name: String::from("Alice"), age: 30, };
alice.age += 1; println!("{} is now {}", alice.name, alice.age);}Adding behavior with methods
Section titled “Adding behavior with methods”You can attach functions to a struct using an impl block. Inside, &self refers to the specific instance the method was called on:
struct Person { name: String, age: u32,}
impl Person { fn greet(&self) { println!("Hi, I'm {} and I'm {}", self.name, self.age); }}
fn main() { let alice = Person { name: String::from("Alice"), age: 30 }; alice.greet();}Output:
Hi, I'm Alice and I'm 30Constructor-style functions
Section titled “Constructor-style functions”A common pattern is a new function inside impl that builds an instance for you, so callers don’t have to write out every field by hand:
struct Person { name: String, age: u32,}
impl Person { fn new(name: &str, age: u32) -> Person { Person { name: name.to_string(), age } }}
fn main() { let bob = Person::new("Bob", 25); println!("{} is {}", bob.name, bob.age);}Notice age on its own inside Person { name: name.to_string(), age } — when a variable has the exact same name as the field, you can skip writing age: age and just write age. Rust calls this field init shorthand.
Printing a struct with derive
Section titled “Printing a struct with derive”Try println!("{:?}", alice) on a struct as written above, and it won’t compile — Rust doesn’t know how to debug-print a custom type unless you tell it to. Add #[derive(Debug)] above the struct to get that for free:
#[derive(Debug)]struct Person { name: String, age: u32,}
fn main() { let alice = Person { name: String::from("Alice"), age: 30 }; println!("{:?}", alice);}Output:
Person { name: "Alice", age: 30 }#[derive(...)] is Rust’s way of auto-generating common functionality for a type — you’ll see Debug, and later Clone and others, added this way constantly.
- A struct groups named fields into one type:
struct Person { name: String, age: u32 }. - Create an instance with
Person { name: ..., age: ... }; mark itmutto change fields later. - Add behavior with an
implblock;&selfrefers to the instance a method was called on. - Add
#[derive(Debug)]to make a struct printable with{:?}.