Defining and Using Structs

  type Point = struct {
    x: f32,
    y: f32,
};

var p = Point { .x = 1.0, .y = 2.0 };
var p: Point = .{ .x = 1.0, .y = 2.0 };  -- type inferred from context

debug.print("({}, {})\n", .{p.x, p.y});
  

Field Defaults

  type Config = struct {
    host:    []const u8 = "localhost",
    port:    u16        = 8080,
    timeout: u32        = 30,
    debug:   bool       = false,
};

var cfg = Config { .host = "example.com" };
-- port, timeout, debug use their defaults
  

Methods

Methods go in impl blocks. Receivers use *self (mutable), *const self (immutable), or self (consuming):

  type Rectangle = struct {
    width:  f32,
    height: f32,
};

impl Rectangle {
    static fn new(width: f32, height: f32): Self {
        return .{ .width = width, .height = height };
    }

    fn area(*const self): f32 {
        return self.width * self.height;
    }

    fn perimeter(*const self): f32 {
        return 2.0 * (self.width + self.height);
    }

    fn scale(*self, factor: f32) {
        self.width  *= factor;
        self.height *= factor;
    }

    fn isSquare(*const self): bool {
        return self.width = self.height;
    }
}

var r = Rectangle::new(3.0, 4.0);
debug.print("area: {}\n", .{r.area()});
r.scale(2.0);
debug.print("scaled area: {}\n", .{r.area()});
  

Visibility

  type BankAccount = struct {
    owner: []const u8,
    pub readonly balance: f64,  -- readable outside, writable inside
    pin:    u32,                -- private
};

impl BankAccount {
    static fn new(owner: []const u8, pin: u32): Self {
        return .{ .owner = owner, .balance = 0.0, .pin = pin };
    }

    pub fn deposit(*self, amount: f64) {
        self.balance += amount;
    }

    pub fn withdraw(*self, amount: f64, pin: u32): !void {
        if pin != self.pin { return error.WrongPin; }
        if amount > self.balance { return error.InsufficientFunds; }
        self.balance -= amount;
    }
}
  

Packed and Extern Structs

For hardware registers and C interop:

  type Flags = packed struct {
    active:   u1,
    mode:     u3,
    reserved: u4,
};

type CVec3 = extern struct {
    x: f32,
    y: f32,
    z: f32,
};