Structs, enums, and newtypes
types/main.xo
struct User {
id: Int
name: Str
email: Str?
} derive Display
enum Shape {
Circle(radius: Float)
Rect(w: Float, h: Float)
Point
}
fn area(s: Shape) -> Float {
match s {
Circle(radius) => 3.14159 * radius * radius
Rect(w, h) => w * h
Point => 0.0
}
}
type UserId = Int
type Email struct(Str)
fn domain(e: Email) -> Str {
e.0.split("@").last() ?? ""
}
fn main(os: Os) {
let ada = User{id: 1, name: "Ada", email: None}
let renamed = ada with {name: "Ada L."}
os.stdio.println("${ada}")
os.stdio.println("${renamed.name}")
let id: UserId = 7
os.stdio.println("user ${id}, area ${area(Shape.Rect(w: 2.0, h: 3.0))}")
os.stdio.println(domain(Email("ada@example.com")))
}Output:
User{id: 1, name: "Ada", email: None}
Ada L.
user 7, area 6.0
example.com
- Constructing a struct names every field, so adding a field later is a compile error at every place that builds one.
u with {name: "..."}makes a modified copy. Structs are values.- Enums are sum types: each variant can carry its own fields, and
matchmust handle every variant. derive Displayprints the value structurally.Json,Eq,Hash, andOrdare derived the same way.type UserId = Intis an alias.type Email struct(Str)is a distinct type, so anEmailcan never be passed where a plainStris expected by accident. Its value ise.0.