Skip to content

04 · Structs

struct groups named fields into a single type. Methods are added in an impl block and take &self for read access or &mut self for mutation. Structs are stack-allocated by default — no hidden heap unless you opt in with !alloc.

structs.cssl
struct Point {
x: f32,
y: f32,
}
impl Point {
// Constructor — associated function, no self.
fn new(x: f32, y: f32) -> Point {
Point { x, y }
}
// Method — borrows self immutably.
fn distance_from_origin(&self) -> f32 {
(self.x * self.x + self.y * self.y).sqrt()
}
// Method — mutates self.
fn translate(&mut self, dx: f32, dy: f32) {
self.x += dx;
self.y += dy;
}
}
fn main() !io {
let mut p = Point::new(3.0, 4.0);
println!("distance = {}", p.distance_from_origin());
p.translate(1.0, 0.0);
println!("after translate: ({}, {})", p.x, p.y);
}
distance = 5
after translate: (4, 4)

Field access on &self is read-only — any attempt to mutate through a shared borrow is a compile error. The Point { x, y } shorthand in the constructor works when the local variable name matches the field name. Struct layout is deterministic and guaranteed stable across compilations for FFI use.


Next → 05 · Enums and Match