Structs

A struct bundles related data under one name, the same job a class's fields do in Java or C# — Rust just separates the data (the struct) from the behavior (an impl block) instead of writing them together.

Defining and creating a struct

Rust src/main.rs
struct Account {
    owner: String,
    balance: f64,
}

fn main() {
    let account = Account {
        owner: String::from("Jamie"),
        balance: 100.0,
    };
    println!("{}: {}", account.owner, account.balance);
}
Output
Jamie: 100

struct Account declares the shape: every account has an owner and a balance, with fixed types. Creating one fills in every field by name; dot syntax reads them back, same as most other languages on this site.

Methods live in an impl block

Behavior attaches to a struct through a separate impl (implementation) block, rather than being declared inside the struct itself:

Rust src/main.rs
struct Account {
    owner: String,
    balance: f64,
}

impl Account {
    fn deposit(&mut self, amount: f64) {
        self.balance += amount;
        println!("Deposited {}. New balance: {}", amount, self.balance);
    }
}

fn main() {
    let mut account = Account { owner: String::from("Jamie"), balance: 100.0 };
    account.deposit(50.0);
}
Output
Deposited 50. New balance: 150

&mut self is a mutable borrow of the struct instance the method was called on — it's how deposit is allowed to change balance. Leaving off mut (just &self) gives a read-only method; leaving off self entirely defines an associated function instead, which is how constructors are conventionally written:

Rust src/main.rs
impl Account {
    fn new(owner: &str) -> Self {
        Self { owner: owner.to_string(), balance: 0.0 }
    }
}

fn main() {
    let account = Account::new("Sasha");
    println!("{} starts with {}", account.owner, account.balance);
}
Output
Sasha starts with 0
Note: Rust has no new keyword and no built-in constructor — Account::new(...) above is just an ordinary associated function that happens to be named new by convention. Self (capital S) inside an impl block is shorthand for the type being implemented, so renaming Account later wouldn't require touching every constructor body.