Data Structures
Structs #
Structs define custom data types with named fields:
struct Point {
x: f64,
y: f64,
}
let p = Point { x: 1.0, y: 2.0 }
print(p.x) // 1.0
Field Shorthand #
When the variable name matches the field name:
let x = 3.0
let y = 4.0
let p = Point { x, y } // same as Point { x: x, y: y }
Default Field Values #
struct Config {
host: str,
port: int,
debug: bool,
}
let cfg = Config { host: "localhost", port: 8080, debug: false }
Implementations (impl) #
Add methods to a struct:
impl Point {
// Method that takes self
fn distance(self) -> f64 {
(self.x ** 2.0 + self.y ** 2.0).sqrt()
}
// Associated function (no self) — constructor
fn new(x: f64, y: f64) -> Point {
Point { x, y }
}
// Method with additional parameters
fn translate(self, dx: f64, dy: f64) -> Point {
Point { x: self.x + dx, y: self.y + dy }
}
}
let p = Point::new(3.0, 4.0)
print(p.distance()) // 5.0
Enums #
Enums define types with named variants:
// Simple variants
enum Color {
Red,
Green,
Blue,
}
// Variants with data (tuple-style)
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
// Variants with named fields
enum Event {
Click { x: int, y: int },
KeyPress(str),
Quit,
}
Creating Enum Values #
let c = Color::Red
let s = Shape::Circle(5.0)
let e = Event::Click { x: 10, y: 20 }
Using Enums with Match #
fn area(shape: Shape) -> f64 {
match shape {
Shape::Circle(r) => 3.14159 * r * r,
Shape::Rectangle(w, h) => w * h,
}
}
Enums with Implementations #
impl Shape {
fn describe(self) -> str {
match self {
Shape::Circle(r) => "Circle with radius {r}",
Shape::Rectangle(w, h) => "Rectangle {w}x{h}",
}
}
}
Traits #
Traits define shared behavior (interfaces):
trait Displayable {
fn display(self) -> str
// Default implementation
fn debug(self) -> str {
"debug: {self.display()}"
}
}
Implementing Traits #
impl Displayable for Point {
fn display(self) -> str {
"({self.x}, {self.y})"
}
}
let p = Point { x: 1.0, y: 2.0 }
print(p.display()) // "(1.0, 2.0)"
print(p.debug()) // "debug: (1.0, 2.0)"
Trait Bounds (Generics) #
fn print_all(items: [T]) where T: Displayable {
for item in items {
print(item.display())
}
}
Arrays #
Arrays are ordered, 0-indexed collections:
let numbers = [1, 2, 3, 4, 5]
print(numbers[0]) // 1
print(numbers[4]) // 5
// Array operations (via standard library)
numbers |> Array.push(6)
numbers |> Array.map(|x| x * 2)
numbers |> Array.filter(|x| x > 3)
See Standard Library for full Array API.
Maps #
Maps are key-value collections:
let scores = { "Alice": 95, "Bob": 87 }
print(scores["Alice"]) // 95
See Standard Library for full Map API.
Modules #
Declaring Modules #
// In math/vectors.zolo
mod math::vectors
pub struct Vec2 {
pub x: f64,
pub y: f64,
}
pub fn dot(a: Vec2, b: Vec2) -> f64 {
a.x * b.x + a.y * b.y
}
Importing #
use math::vectors::{Vec2, dot}
let v = Vec2 { x: 1.0, y: 0.0 }
Visibility #
pubmakes items visible outside the module- Without
pub, items are module-private