Structs
Named product types with optional field defaults, impl blocks for methods, operator overloading, and struct-update spread syntax.
Summary
Fields can carry type annotations and default values. Methods are added in separate impl TypeName { ... } blocks; self is an explicit first parameter. Operator overloading works by naming a method with the operator symbol. The spread/update syntax Type { ...existing, field: val } creates a new instance based on an existing one. The derives clause (or #[derive(...)]) auto-implements traits like Eq and Hash.
Canonical
struct Point { x, y }
-- create an instance
let p = Point { x: 10, y: 20 }
println(p.x) -- 10
println(p.y) -- 20
-- with type annotations on fields
struct Config {
host: str,
port: int,
debug: bool
}
-- field defaults
struct Options {
verbose = false,
retries: int = 3,
timeout: f64 = 30.0
}
let opts = Options {} -- all defaults
let opts2 = Options { verbose: true } -- override one
-- derives: auto-implement traits
struct Vec2 { x, y } derives Eq, Hash
-- #[derive(...)] attribute syntax (equivalent)
#[derive(Eq, Hash)]
struct Vec3 { x, y, z }Impl Blocks
Add methods to structs with impl:
impl Point {
fn distance(self) {
return sqrt(self.x * self.x + self.y * self.y)
}
fn translate(self, dx, dy) {
return Point { x: self.x + dx, y: self.y + dy }
}
}
let p = Point { x: 3, y: 4 }
println(p.distance()) -- 5
let moved = p.translate(1, 0)
println(moved.x) -- 4Methods that access instance data take self as the first parameter. self is not implicit.
Operator Overloading
Define operators as methods in impl blocks by using the operator as the function name:
struct Vec2 { x, y }
impl Vec2 {
fn +(self, other) {
return Vec2 { x: self.x + other.x, y: self.y + other.y }
}
fn *(self, scalar) {
return Vec2 { x: self.x * scalar, y: self.y * scalar }
}
}
let a = Vec2 { x: 1, y: 2 }
let b = Vec2 { x: 3, y: 4 }
let c = a + b
println(c.x) -- 4
println(c.y) -- 6Overloadable operators: +, -, *, /, %, ==, !=, <, >, <=, >=, ++, &&, ||.
Spread / Update Syntax
Create a new struct based on an existing one, overriding specific fields:
let p = Point { x: 10, y: 20 }
let p2 = Point { ...p, y: 30 }
println(p2.x) -- 10
println(p2.y) -- 30Struct Destructuring
let Point { x: a, y: b } = Point { x: 100, y: 200 }
println(a) -- 100
println(b) -- 200