Skip to main content

Structs

Structs are Zynx's primary user-defined data type for modeling state and attaching behavior.

They support:

  • named fields
  • methods (including operator methods)
  • init and drop lifecycle hooks
  • interface implementation
  • generic parameters

Defining a Struct

struct Point {
x: i32,
y: i32,
}

Create values with struct literals:

let p = Point { x: 10, y: 20 };

Methods

Define methods inside the struct body:

struct Counter {
value: i32,

fn inc(self, by: i32) {
self.value += by;
}

fn get(self) -> i32 {
return self.value;
}
}
  • Instance methods take self.
  • Methods without a self parameter are automatically treated as static.

init and drop

Structs can define lifecycle hooks:

struct FileHandle {
fd: i32,

init(self, fd: i32) {
self.fd = fd;
}

drop(self) {
// cleanup logic
}
}
  • init is used for custom construction.
  • drop runs at scope end for deterministic cleanup.
  • If a field has no default value, init must initialize it.

Visibility and Mutability Attributes

Field-level controls:

  • @private – field access is restricted to the struct's own methods.
  • @readonly – field mutation is restricted to the struct's own methods.

Layout-related attributes:

  • @packed – removes padding between fields.
  • @align(N) – enforces minimum alignment.

Interfaces and Generics

Structs can implement interfaces:

interface Addable<T> {
+(self, other: const &T) -> T;
}

struct Number : Addable<Number> {
val: i32,

+(self, other: const &Number) -> Number {
return Number { val: self.val + other.val };
}
}

And can be generic:

struct Box<T> {
value: T,
}

Operator Methods

Struct methods can overload operators directly (+, -, [], +=, etc.).

See Operators for the full reference.

See also