match
The match block is compare a value against multiple patterns and executes the code according to the first pattern that matches.
Patterns
Literal Patterns
Match for exact values using literals like "apple", 42, @(1.5, 2.5), #bb00ff, $banana, true or null:
let x = "banana"
match x {
"apple" => Print { "It's an apple!" },
"banana" => Print { "It's a banana!" },
}
Wildcard Patterns
Use _ to match for any value. This is useful for providing a default case when no other patterns match:
let x = $banana
match x {
$apple => Print { "It's an apple!" },
$banana => Print { "It's a banana!" },
_ => Print { "It's something else!" },
}
Predicate Patterns
Use functions like IsNum, IsString or IsArray to match for types:
let x = "banana"
match x {
IsNum => Print { "It's a number!" },
IsString => Print { "It's a string!" },
_ => Print { "It's something else!" },
}
Any function that takes one argument and returns a boolean can be used as a pattern in a match block.
This includes most functions in the Types category of the reference section,
but you can also define your own.
Array Patterns
Use square brackets [] to match an Array.
Each element of the array can be matched against a different pattern:
let x = [$banana, 100]
match x {
[$apple, _] => Print { "It's an apple!" },
[$banana, _] => Print { "It's a banana!" },
_ => Print { "It's something else!" },
}
The length of the array must be an exact match for the pattern to match:
let x = [1, 2, 3]
match x {
[_, _] => Print { "It's an array of length 2!" },
[_, _, _] => Print { "It's an array of length 3!" },
_ => Print { "It's something else!" },
}
Map Patterns
Use curly braces {} to match a Map.
Each field of the map can be matched against a different pattern:
let x = { type = $banana, points = 100 }
match x {
{ type = $apple } => Print { "It's an apple!" },
{ type = $banana } => Print { "It's a banana!" },
}
Only the fields specified in the pattern are checked for a match. The Map may contain additional fields that are not specified in the pattern.
Alternative Patterns
Use | to specify multiple alternative patterns.
As long as one of the alternative patterns matches, the code will be executed:
let x = "banana"
match x {
"apple" | "banana" => Print { "It's a fruit!" },
"potato" | "pumpkin" => Print { "It's a vegetable!" },
_ => Print { "It's something else!" },
}
Multiple Values
Use commas to match for multiple values at the same time:
let x = "banana"
let y = "jimmy"
match x, y {
"apple", "jimmy" => Print { "Give an apple to Jimmy!" },
"banana", "jimmy" => Print { "Give a banana to Jimmy!" },
"apple", "jane" => Print { "Give an apple to Jane!" },
"banana", "jane" => Print { "Give a banana to Jane!" },
}
The | has higher precedence than the comma.
In the following example, the first pattern will match either an apple or a banana, but only if the second value is "jimmy":
let x = $banana
let y = $jimmy
match x, y {
$apple | $banana, $jimmy => Print { "Give a fruit to Jimmy!" },
$pumpkin | $potato, $jimmy => Print { "Give a vegetable to Jimmy" },
$apple | $banana, $jane => Print { "Give a fruit to Jane!" },
$pumpkin | $potato, $jane => Print { "Give a vegetable to Jane!" },
}
As commas have lower precedence than the |, use parentheses to specify alternatives to all the values:
let x = $banana
let y = $jimmy
match x, y {
($apple, $jimmy) | ($banana, $jane) => Print { "The citizens are been satisfied" },
($apple, $jane) | ($banana | $pumpkin, $jimmy) => Print { "The citizens are rioting" },
}
Match Arms
Each match arm can have a single statement or a block of code, surrounded by curly braces {}:
let x = "banana"
match x {
"apple" => Print { "It's an apple!" },
"banana" => {
Print { "It's a banana!" }
Spawn unit { BananaMonster }
},
}
Returning Values
Match blocks can also be used as expressions. The last line of each arm determines the resulting value of that arm.
let x = "banana"
let scoreChange = match x {
"apple" => 100,
"banana" => {
Print { "It's a banana!" }
Spawn unit { BananaMonster }
-100
},
}
Returning Multiple Values
To return multiple values, use commas and wrap the values in parentheses:
let x = "banana"
let color, scoreChange = match x {
"apple" => (#ff0000, 100),
"banana" => {
Print { "It's a banana!" }
Spawn unit { BananaMonster }
(#ffff00, -100)
},
}
If you call a function that returns multiple values, all values will pass through the match block:
pub fn Example1() {
x = $banana
let color, scoreChange = match x {
"apple" => GiveMeAnApple,
"banana" => GiveMeABanana,
}
}
pub fn GiveMeAnApple() -> color, scoreChange {
return #ff0000, 100
}
pub fn GiveMeABanana() -> color, scoreChange {
return #ffffff, -100
}
Declaring Variables
You can declare the result of the match expression as a new variable using the let or use keywords:
match let x = GiveMeAGift {
IsNum => Print { "The gift of numbers: " + x },
IsString => Print { "Some words for you: " + x },
}
See Local Variables to learn more about the let and use keywords.