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.