Skip to content

Structs, enums, and match

class and struct are the same data shape. Methods take explicit self. Inheritance uses open / extends / override (see below).

struct User {
name: String
age: int
fn greet(self) -> String {
return "hello " + self.name
}
}
fn main(caps: Caps) -> int {
var u = User { name: "Ada", age: 36 }
u.age = 37
print u.greet()
return u.age
}

Field assign needs a var binding (or a mutable field context the compiler allows).

enum Shape {
Circle(int),
Rect(int, int)
}
fn area(s: Shape) -> int {
return match s {
Circle(r) => 3 * r * r,
Rect(w, h) => w * h
}
}
fn main(caps: Caps) -> int {
let a = area(Shape::Circle(2))
let b = area(Shape::Rect(3, 4))
return a + b
}

If you omit Rect, vow check fails. That is the point — especially for AI-generated near-misses.

// type error: non-exhaustive match
fn bad(s: Shape) -> int {
return match s {
Circle(r) => r
}
}

Share state with a nested field, or use single inheritance:

open class Animal {
name: String
fn speak(self) -> String {
return "..."
}
}
class Dog extends Animal {
breed: String
override fn speak(self) -> String {
return "woof"
}
}

Rules: classes closed by default (open to subclass); override mandatory; single inheritance only. Prefer interfaces for shared behavior without dragging fields.