Scala - pattern matching
7. 6. 2011 (před 9 lety) — k47 (CC by)

Seznam všechn způsobů, jak lze provádět pattern matching:
a match { case a => // shoda pro jakoukoli hodnotu case _ => // to samé, ale bez pojmenované proměnné case a: Something => // case a if a.isInstanceOf[Something] && a != null // pro null nikdy nenastane shoda case Something => // case a if a == Something, toto pravidlo je použito v případě `case None' nebo `case Nil' case Something() => // case a: Something case A(b) => case `variable` => // case v if v == variable case A(`b`) => // case A(x) if x == b case A(B) => // case A(b) if b == B // pokud název proměnné začíná velkým písmenem nebo je v zpětných apostrofech, bere se jako konstanta case A("string literal") => // lze použít jakýkoli literál (Int, String, Boolean, Char, Symbol) case A(a, B(C(c), b)) => // vzory lze libovolně vnořovat case A(_, a) => // pojmenovat můžeme jenom některé proměnné case A() | B() => // odpovídá jednomu ze dvou vzorů case A(_) | B(_, _) => // není možné pojmenovat parametry case b @ B(x, y) => // objekt B je zachycen do proměnné `b' a zároveň jsou zachyceny jeho dílčí části v `x' a `y' case B(a @ A(_), _) => // @ konstrukci lze pochopitelně libovolně zanořovat case a: Array[Int] => // můžeme se dotazovat na typový parametr polí case a: List[_] => // ale ne na typ. param. ostatních generických typů (jinak nás uvítá unchecked warning) // sekvence case List(0, 1, 2) => // seznam, který má délku 3 a obsahuje položky: 1, 2, 3 case List(1, _, _) => // seznam, který má délku 3 a začíná integerem 1 case List(1, _*) => // seznam délky > 1, který začíná integerem 1 case (a, b, c) => // case Tuple3(a, b, c) case 1 :: Nil => // infixový vzor, obdoba `case List(1)' nebo přesněji `case ::(1, Nil)' case 1 :: 2 :: _ => // obdoba `case ::(1, ::(2, _)' nebo `case List(1, 2, _*)' }
A nejlepší je, že soukolí pattern matchingu můžete používat i v definici
proměnných. Téměř všechno, co může následovat case
, může másledovat val
.
val myTuple = (123, "xxx") val (a, b) = myTuple val List(1, _, 3) = myList
dokonce můžete použít i takovéhle zrůdnosti:
val a @ Some(b) = Some(1) // a = Some(1); b = 1
Maličkým problémem může být, že pokud nenastane shoda, uvítá vás přátelská
MatchError
.
Ještě jedna drobnost: pokud definujete třídu s několika skupinami argumentů, pattern matching lze provádět jen na první z nich.
case class A(a: Int)(b: String) A(1)("something") match { case A(_)(_) => // není možné case A(_) => // tohle je už lepší }