Pattern Matching
Powerful pattern matching with match expressions, destructuring, and guard clauses.
Basic Match
match
Match a value against patterns and execute corresponding code.
let x = 42;
let result = match x {
42 => "the answer",
0 => "zero",
_ => "something else",
};
print(result); // "the answer"
Guard Clauses
Add conditions to patterns using if guards:
let n = 5;
let category = match n {
n if n < 0 => "negative",
0 => "zero",
n if n > 0 && n < 10 => "single digit positive",
n if n >= 10 && n < 100 => "two digit positive",
_ => "large number",
};
print(category); // "single digit positive"
// Practical example: HTTP status handling
fn handle_status(code: Int) -> String {
return match code {
code if code >= 200 && code < 300 => "Success: " + str(code),
code if code >= 300 && code < 400 => "Redirect: " + str(code),
404 => "Not Found",
500 => "Internal Server Error",
code if code >= 500 => "Server Error: " + str(code),
_ => "Client Error: " + str(code),
};
}
print(handle_status(200)); // "Success: 200"
print(handle_status(404)); // "Not Found"
Array Patterns
let numbers = [1, 2, 3];
// Match array length
let description = match numbers {
[] => "empty array",
[_] => "single element array",
[_, _] => "two element array",
[_, _, _] => "three element array",
_ => "array with more than 3 elements",
};
// Destructuring arrays
let result = match numbers {
[first] => "First element is: " + str(first),
[first, second] => "First: " + str(first) + ", Second: " + str(second),
[first, second, third] => "Three elements",
[first, ...rest] => "First: " + str(first) + ", Rest has " + str(len(rest)) + " elements",
};
// Rest pattern
let arr = [1, 2, 3, 4, 5];
match arr {
[first, second, ...rest] => {
print("First two: " + str(first) + ", " + str(second));
print("Remaining: " + str(rest)); // [3, 4, 5]
},
};
Hash Patterns
let user = {"name": "Alice", "age": 30, "city": "Paris"};
// Match hash structure
match user {
{} => "empty object",
{name: n} => "name is: " + n,
{name: n, age: a} => n + " is " + str(a) + " years old",
{name: n, age: a, city: c} => n + " is " + str(a) + " years old and lives in " + c,
_ => "unknown structure",
};
// Nested hash matching
let data = {
"user": {"name": "Alice", "email": "[email protected]"},
"posts": [{"title": "Post 1"}, {"title": "Post 2"}]
};
match data {
{user: {name: n}, posts: posts} => {
print(n + " wrote " + str(len(posts)) + " posts");
},
_ => "no match",
};
Type-Based Dispatch
fn describe_value(val: Any) -> String {
return match val {
s: String => "String with " + str(len(s)) + " characters",
n: Int => "Integer: " + str(n),
f: Float => "Float: " + str(f),
b: Bool => "Boolean: " + str(b),
arr: Array => "Array with " + str(len(arr)) + " elements",
h: Hash => "Hash with " + str(len(h)) + " keys",
null => "Null value",
_ => "Unknown type: " + type(val),
};
}
print(describe_value("hello")); // "String with 5 characters"
print(describe_value(42)); // "Integer: 42"
print(describe_value([1, 2, 3])); // "Array with 3 elements"
Wildcard Pattern
_
Wildcard / Default Case
Matches any value. Use as a default/catch-all case.
let status = "unknown";
let message = match status {
"active" => "User is active",
"inactive" => "User is inactive",
_ => "Status: " + status, // Default case
};