Struct
struct is a composite type with value semantics: assignment and argument passing copy the whole thing, and changing a copy leaves the original untouched. A good fit for small, self-contained data such as coordinates or config entries.
Declaration and Construction
struct Point
{
public var x: int = 0;
public var y: int = 0;
public func Show() -> string => $"({x}, {y})";
}
struct Pair
{
public val a: string;
public val b: string;
init(a: string, b: string)
{
self.a = a;
self.b = b;
}
}Construction goes through new: a struct without a constructor can be created directly with new Point(), yielding an instance with all fields at their zero values; a struct with a constructor requires arguments matching its signature:
val p = new Point();
print(p.Show());
val q = new Point() { x: 3, y = 4 };
print(q.Show());
val pr = new Pair("a", "b");(0, 0)
(3, 4)The object initializer { field: value } (: or = both work) assigns field by field after construction. Fields declared with an initializer start from the declared value; the rest take the type’s zero value.
Value Semantics
val q = new Point() { x: 3, y: 4 };
var r = q;
r.x = 99;
print(q.x, r.x);3 99r = q copies the whole value; the two variables are independent afterwards. This is the core difference between struct and class: put the same code on a class and both sides end up 99.
Value Semantics in Containers
Structs keep value semantics inside containers too: what you read from an index is a copy, and changing the copy does not write back. The one exception is the index-position direct field write, which targets the container element itself:
var xs = new list<Point>();
xs.Add(new Point() { x: 1 });
xs[0].x = 5;
print(xs[0].x);
var p = xs[0];
p.x = 9;
print(xs[0].x, p.x);5
5 9xs[0].x = 5 writes into the container; var p = xs[0] copies out first, so the later p.x = 9 changes only the copy.
Reference-type fields inside a nested struct (class references, containers, and so on) still copy the reference itself, pointing at the same object.
Fields and Methods
- Fields have three kinds of binding:
val(immutable; every explicit constructor must assign it),var(mutable), andconst(compile-time constant). Fields without a modifier default to private. - Methods take
selfas their first parameter (or use a bareself); inside the body, the struct’s own members are accessed directly by field name. - The primary constructor form
struct Name(args) { }promotes the parameters to private val fields, saving you from writing an init by hand.
Constructor Delegation
Constructors delegate to each other with : init(...), avoiding duplicated assignment logic:
struct Gauge
{
public val id: int;
public var hits: int = 0;
init(id: int)
{
self.id = id;
}
init() : init(0)
{
}
}
val c = new Gauge(7);
print(c.id, c.hits);
val c0 = new Gauge();
print(c0.id);7 0
0The primary constructor form struct Gauge(id: int) promotes the parameters to private val fields, which suits pure data aggregation; write an explicit init when you need logic.
with: Non-Destructive Updates
Immutable data structures derive new values with with instead of mutating the original instance. with chains: each level produces a new copy:
struct Point3
{
public var x: int = 0;
public var y: int = 0;
public var z: int = 0;
}
val q = new Point() { x: 3, y: 4 };
val moved = q with { x: 10 };
print(q.Show(), moved.Show());
val p3 = new Point3() { x: 1, y: 2, z: 3 };
val stepped = p3 with { x: 10 } with { y: 20 };
print(stepped.x, stepped.y, stepped.z);
val half = new Point3() { z: 9 } with { y: 5 };
print(half.x, half.y, half.z);(3, 4) (10, 4)
10 20 3
0 5 9Fields missing from the initializer take the type’s zero value (half’s x is 0), and with fills in level by level. with also supports chaining and nested blocks; see Vectors and Colors for the same semantics.
Notes
- Generic structs
struct Box<T> { }, protocol implementationsstruct Tag impl Greeter, and constraintswhere T: ...all compose with struct. - A constructor can declare a
failclause;new Gauge(args)is then a fallible expression and the call site must consume it; see Failure. - Structs have no inheritance; reuse behavior through protocols and mixins.
