Skip to content

Structs & Records

struct declares a nominal type:

struct Point {
Int x;
Int y;
}
struct Offset {
Int x, y;
}

Int x, y; is shorthand for two fields of the same type.

Structs without custom init can use field literals:

Point point = Point { x: 0, y: 0 }
Point^ heap_point = new (Point { x: 100, y: 200 });

Owning pointers do not auto-dereference in assignment, initialization, or arithmetic value contexts. Field access can pass through T^:

print(heap_point.x);

A field is writable only when the field type itself is mutable:

struct User {
Int id;
Int! age;
UInt8[]? nick_name;
}
User user = User { id: 123, age: 18 }
user.age = user.age + 1;
// user.id = 200; // error

init is a constructor entry in a struct or record body:

struct Point {
Int x;
Int y;
init(Int x, Int y) {
self.x = x;
self.y = y;
return ();
}
init(Int value) {
self.x = value;
self.y = value;
return ();
}
}
Point p1 = Point(1, 2);
Point p2 = Point(3);
Point^ p3 = new Point(4, 5);

Use init(...) for ordinary constructors. Jiang also reserves additional init forms for named or fallible construction.

deinit is declared without a return type:

struct Buffer {
UInt8[*] data;
deinit() {
self.data$.free();
return ();
}
}

Types can define static methods and instance methods:

struct User {
Int id;
static Int zero() {
return 0;
}
Int value() {
return self.id;
}
}
Int a = User.zero();
User u = User { id: 42 }
Int b = u.value();

record is written like a lightweight data type with named fields:

record PointRecord {
Int x;
Int y = 2;
}
PointRecord p1 = PointRecord { x: 40 }
PointRecord p2 = PointRecord { x: 1, y: 2 }

Record fields can have default values and same-type multi-field declarations.

Local variable declarations bind one name at a time:

Int a = 1;
Int b = 2;
Int c = 3;