Structs and impl Structs are named product types. Methods go in an impl block. Operators, spread syntax, and destructuring apply to any struct without extra opt-in.
struct Point { x , y }
let p = Point { x : 10 , y : 20 }
println ( p . x ) -- 10
println ( p . y ) -- 20
Fields can have type annotations and defaults:
struct Config {
host : str ,
port : int ,
debug : bool
}
struct Options {
verbose = false ,
retries : int = 3 ,
timeout : float = 30.0
}
let opts = Options { }
println ( opts . retries ) -- 3
let custom = Options { verbose : true }
println ( custom . verbose ) -- true
println ( custom . retries ) -- 3
Methods take self explicitly. Static methods (no self) use the static keyword.
struct Point { x , y }
impl Point {
fn distance ( self ) -> float {
return ( self . x * self . x + self . y * self . y ) ** 0.5
}
fn translate ( self , dx , dy ) {
return Point { x : self . x + dx , y : self . y + dy }
}
static fn origin ( ) {
return Point { x : 0 , y : 0 }
}
}
let p = Point { x : 3 , y : 4 }
println ( p . distance ( ) ) -- 5.0
let moved = p . translate ( 1 , 0 )
println ( moved . x ) -- 4
let o = Point :: origin ( )
println ( o . x ) -- 0
Define operators as method names in an impl block. Overloadable:+, -, *, /, %, ==, !=, <, >, <=, >=, ++, &&, ||.
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 }
}
fn == ( self , other ) {
return self . x == other . x and self . y == other . y
}
}
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 ) -- 6
let scaled = a * 3
println ( scaled . x ) -- 3
Create a new struct based on an existing one, overriding specific fields. The original is not modified.
struct Point { x , y }
let p = Point { x : 10 , y : 20 }
let p2 = Point { . . . p , y : 30 }
println ( p . y ) -- 20 (unchanged)
println ( p2 . x ) -- 10 (copied from p)
println ( p2 . y ) -- 30 (overridden)
struct Point { x , y }
let p = Point { x : 100 , y : 200 }
let Point { x : px , y : py } = p
println ( px ) -- 100
println ( py ) -- 200
-- works in match too
match p {
Point { x , y } => println ( " ( {x} , {y} ) " )
_ => { }
}
Auto-implement common traits with derives or the #[derive(...)] attribute syntax:
struct Vec2 { x , y } derives Eq , Hash
let a = Vec2 { x : 1 , y : 2 }
let b = Vec2 { x : 1 , y : 2 }
println ( a == b ) -- true
Structs are data-oriented. For OOP with inheritance, see Classes and traits . For shared behaviour across types, see the traits section of the same page.