Nedávno som sa hlbšie venoval práve pattern match syntaxe. Podľa mňa nejde len o nejaký vylepšený switch/case, ale o fundamentálne hlbší spôsob analýzy dát.
Práve v poslednej dobe sa pattern match pridal do viacerých jazykov: PHP, Python, Groovy (switch expression), Java či C#. Hodnotenie: Java (bieda), Python, PHP (slabé), Kotlin, C#, Rust, Scala (OK), Groovy, F# (excelentné).
Raku je pravdepodobne tiež veľmi dobré; Clojure tuším zo svojej podstaty pattern match nepotrebuje.
Ináč jednotlivým voľbám sa hovorí arms ako protikladu branches pri klasickom switch/case.
Tie excelentné jazyky majú guards, ranges, a množstvo spôsobov ako rozpitvať dátové štruktúry. Pattern match je výraz, ktorý vracia hodnotu. Podporujú priamy regex match.
def rnd = new Random()
def ri = rnd.nextInt(-5, 5)
def res = switch (ri) {
case { ri < 0 } -> "${ri}: negative value"
case { ri == 0 } -> "${ri}: zero"
case { ri > 0 } -> "${ri}: positive value"
}
println res
Tento Groovy príklad ukazuje priradenie voľby do premennej a guards.
def rnd = new Random()
def ri = rnd.nextInt(0, 120)
switch (ri) {
case 1..30 -> println('value is in the range from 1 to 30')
case 31..60 -> println('value is in the range from 31 to 60')
case 61..90 -> println('value is in the range from 61 to 90')
case 91..120 -> println('value is in the range from 91 to 120')
}
Groovy a ranges.
def words = ['week', 'bitcoin', 'cloud', 'copper', 'raw', 'war',
'cup', 'water']
def selected = []
for (word in words) {
def res = switch (word) {
case ~/^w.*/ -> word
case ~/^c.*/ -> word
default -> 'skip'
}
if (res != 'skip') {
selected.add(res)
}
}
println selected
Groovy a regex výrazy.
open System
printf "Enter a number: "
let value = Console.ReadLine()
let n =
match Int32.TryParse value with
| true, num -> num
| _ -> failwithf "'%s' is not an integer" value
let f = function
| value when value > 0 -> printfn "positive value"
| value when value = 0 -> printfn "zero"
| value when value < 0 -> printfn "negative value"
f (int value)
f n
F# a spracovanie chýb.
let grades = ["A"; "B"; "C"; "D"; "E"; "F"; "FX"]
for grade in grades do
match grade with
| "A" | "B" | "C" | "D" | "E" | "F" -> printfn "%s" "passed"
| _ -> printfn "%s" "failed"
F# a viacnásobné voľby, ktoré výrazne skracujú zápis.