Enums
Enums in Nic are algebraic data types (ADTs). Each variant can hold different data, making them powerful for modeling state and results.
Simple Enums
nic
enum Color {
Red,
Green,
Blue
}
fn main() -> unit {
let c: Color = Red;
match c {
Red -> println("red"),
Green -> println("green"),
Blue -> println("blue")
};
return;
}Enums with Data
Variants can carry values:
nic
enum Shape {
Circle(f64), // radius
Rectangle(f64, f64), // width, height
Point // no data
}
fn area(s: Shape) -> f64 {
return match s {
Circle(r) -> 3.14159 * r * r,
Rectangle(w, h) -> w * h,
Point -> 0.0
};
}
fn main() -> unit {
let circle: Shape = Circle(5.0);
let rect: Shape = Rectangle(10.0, 20.0);
let a1: f64 = area(circle); // ~78.5
let a2: f64 = area(rect); // 200.0
return;
}Option Type
The prelude provides Option[T] for optional values:
nic
enum Option[T] {
Some(T),
None
}
fn find(arr: []i32, target: i32) -> Option[i32] {
// ... search logic
return None;
}
fn main() -> unit {
let maybe: Option[i32] = Some(42);
match maybe {
Some(x) -> println("found"),
None -> println("not found")
};
return;
}Use helper functions from the prelude:
nic
fn main() -> unit {
let opt: Option[i32] = Some(42);
let value: i32 = unwrap_or(opt, 0); // 42
let has_value: bool = is_some(opt); // true
let is_empty: bool = is_none(opt); // false
return;
}Result Type
For error handling, use Result[T, E]:
nic
enum Result[T, E] {
Ok(T),
Err(E)
}
fn divide(a: f64, b: f64) -> Result[f64, string] {
if b == 0.0 {
return Err("division by zero");
}
return Ok(a / b);
}
fn main() -> unit {
let result: Result[f64, string] = divide(10.0, 2.0);
match result {
Ok(value) -> println("success"),
Err(msg) -> println("error")
};
return;
}Generic Enums
nic
enum List[T] {
Nil,
Cons(T, *List[T])
}
fn length[T](list: *List[T]) -> i32 {
return match *list {
Nil -> 0,
Cons(_, tail) -> 1 + length(tail)
};
}Record Variants
Variants can have named fields:
nic
enum Event {
Click{x: i32, y: i32},
KeyPress{key: char},
Quit
}
fn handle(e: Event) -> unit {
match e {
Click{x: x, y: y} -> println("click"),
KeyPress{key: k} -> println("key"),
Quit -> println("quit")
};
return;
}Recursive Enums
Enums can reference themselves through pointers:
nic
enum Tree[T] {
Leaf(T),
Node(*Tree[T], *Tree[T])
}
fn count_leaves[T](tree: *Tree[T]) -> i32 {
return match *tree {
Leaf(_) -> 1,
Node(left, right) -> count_leaves(left) + count_leaves(right)
};
}Visibility
nic
pub enum PublicEnum {
VariantA,
VariantB(i32)
}Summary
| Feature | Syntax |
|---|---|
| Simple | enum Name { A, B, C } |
| With data | enum Name { A(T), B(T, U) } |
| Record variant | enum Name { A{field: T} } |
| Generic | enum Name[T] { A(T), B } |
| Match | match value { Variant(x) -> expr } |
Next
Dive deeper into Pattern Matching.