Sum Types, Type Aliases and Smart Casting
17.1 Sum Types (Tagged Unions)
Sum types can include primitives: type Value = int | string | f64 | bool | []Value | map[string]Value (a recursive JSON-like value).
match on a sum type must be exhaustive.
struct Circle { radius f64 }
struct Square { side f64 }
struct Triangle { base f64 height f64 }
type Shape = Circle | Square | Triangle
fn area(s Shape) f64 {
return match s {
Circle { 3.14159 * s.radius * s.radius } // s is smart-cast to Circle
Square { s.side * s.side }
Triangle { 0.5 * s.base * s.height }
}
}
fn main() {
shapes := [Shape(Circle{2}), Square{3}, Triangle{4, 5}]
for s in shapes {
println('${s.type_name()}: ${area(s)}')
}
c := shapes[0]
if c is Circle {
println(c.radius) // smart cast
}
sq := shapes[1] as Square // explicit cast (panics on mismatch)
_ = sq
}17.2 Recursive Sum Types (ASTs)
struct BinOp {
op string
left Expr
right Expr
}
type Expr = int | BinOp
fn eval(e Expr) int {
return match e {
int { e }
BinOp {
l := eval(e.left)
r := eval(e.right)
match e.op { '+' { l + r } '*' { l * r } else { 0 } }
}
}
}17.3 Type Aliases (Distinct Types)
Aliases let you add methods to primitive-based types and improve type safety.
type UserId = int // a new named type based on int
type Celsius = f64
fn (c Celsius) to_f() f64 { return f64(c) * 9 / 5 + 32 }
id := UserId(42)
temp := Celsius(36.6)
println(temp.to_f())17.4 Smart Casting Rules
After if x is T or inside match x { T { ... } }, x is treated as T.
For mutable variables, use if mut x is T to get a mutable smart cast.
Smart casting works on sum types and interfaces (and on struct fields of those types).