Structs
A struct groups named values into a single type. They're Kestrel's go-to for representing data — points, requests, configurations, anything where you want a fixed set of fields with known types.
A first struct
struct Point {
let x: Int
let y: Int
}
let origin = Point(x: 0, y: 0);
let p = Point(x: 3, y: 4);
println("(\(p.x), \(p.y))");
Two fields, both let, both Int. The compiler synthesizes a memberwise initializer that takes one labeled argument per field — that's why Point(x: 0, y: 0) works without you writing an init.
Mutability
Mark a field var to make it writable:
struct Counter {
var value: Int
}
var c = Counter(value: 0);
c.value = c.value + 1;
Writing through c.value requires c to be var itself. A let counter is fully frozen, regardless of whether its fields are let or var.
Methods
Methods can be declared in the struct body or in extend blocks:
extend Point {
func distance(to other: Point) -> Float64 {
let dx = self.x - other.x;
let dy = self.y - other.y;
Float64(from: dx * dx + dy * dy).sqrt()
}
}
println("\(origin.distance(to: p))"); // 5
mutating methods write to var fields. static methods don't need an instance. See Methods for the full coverage.
What's in this section
- Fields —
letvsvar, defaults, type annotations - Methods — instance, mutating, and static
- Initializers — custom
initand the memberwise default - Deinitializers — cleanup hooks at scope exit
- Computed Variables — properties derived from other state
- Subscripts — defining
obj(key)access on your own types
For sum types (variants instead of fields), see Enums. For abstracting over multiple struct types, see Protocols.