Structs & Enums
Define custom data types with structs and algebraic data types with enums.
Struct Definitions
struct Point {
x: i64,
y: i64,
}
fn main() {
let p = Point { x: 3, y: 4 }
print(p.x) // 3
print(p.y) // 4
}Mutable Struct Fields
fn main() {
let mut p = Point { x: 0, y: 0 }
p.x = 10
p.y = 20
print(p.x) // 10
}Impl Blocks and Methods
Attach methods to structs with impl blocks:
struct Rectangle {
width: f64,
height: f64,
}
impl Rectangle {
fn area(self) -> f64 {
self.width * self.height
}
fn is_square(self) -> bool {
self.width == self.height
}
}
fn main() {
let r = Rectangle { width: 10.0, height: 5.0 }
print(r.area()) // 50.0
print(r.is_square()) // false
}Generic Structs
struct Point<T> {
x: T,
y: T,
}
fn main() {
let int_point = Point { x: 1, y: 2 }
let float_point = Point { x: 1.5, y: 2.5 }
}Derive Attributes
Auto-generate trait implementations with @derive:
@derive(Eq, Clone, Display)
struct Point { x: i64, y: i64 }
fn main() {
let a = Point { x: 1, y: 2 }
let b = Point { x: 1, y: 2 }
if a == b { print("equal!") } // @derive(Eq)
let c = clone(a) // @derive(Clone)
print(a) // @derive(Display) -> "Point { x: 1, y: 2 }"
}Enum Definitions
Enums define types with a fixed set of variants. Use the type keyword:
type Color {
Red,
Green,
Blue,
}
fn describe(c: Color) -> str {
match c {
Red => "red"
Green => "green"
Blue => "blue"
}
}
fn main() {
let c = Color.Green
print(describe(c)) // green
}Data-Carrying Variants
Enum variants can carry data, making them algebraic data types:
type Shape {
Circle(f64)
Rectangle(f64, f64)
}
fn describe(s: Shape) -> str {
match s {
Circle(r) => "circle with radius"
Rectangle(w, h) => "rectangle"
}
}
type Option<T> {
Some(T)
None
}Error Handling
Turbo uses Result types T ! E for recoverable errors and Optional types T? for absent values:
// Result type: success or error
fn divide(a: f64, b: f64) -> f64 ! str {
if b == 0.0 {
return err("division by zero")
}
a / b
}
// Propagate errors with ?
fn safe_math(x: f64, y: f64) -> f64 ! str {
let result = divide(x, y)?
result * 2.0
}
// Optional: provide a default with ??
fn find_user(id: i64) -> str? {
// returns None if not found
}
fn main() {
let name = find_user(42) ?? "anonymous"
}