14.15. Definiowanie funkcji za pomocą ciągu klauzul case
Scala umożliwia zastosowanie specjalnej składni do tworzenia funkcji anonimowych, która polega na umieszczeniu w nawiasach klamrowych ciągu klauzul case, takich jak używane w wyrażeniu match. Plik CaseFunctions1.scala zawiera definicję funkcji zwracającej pozdrowienie w różnych językach, zdefiniowanej przy użyciu takiej składni.
Plik CaseFunctions1.scala: val hello1: PartialFunction[String,String] = { case "en" => "Hello!" case "it" => "Ciao!" }
Poniższe polecenia ilustrują sposoby wykorzystania funkcji hello1.
scala> :load CaseFunctions1.scala
Loading CaseFunctions1.scala...
hello1: PartialFunction[String,String] = <function1>
scala> hello1.isDefinedAt("en")
res0: Boolean = true
scala> hello1("en")
res1: String = Hello!
scala> hello1("it")
res2: String = Ciao!
Wywołanie funkcji dla nieobsługiwanego argumentu skutkuje wystąpieniem wyjątku.
scala> hello1.isDefinedAt("fr")
res3: Boolean = false
scala> hello1("fr")
scala.MatchError: fr (of class java.lang.String)
at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:253)
at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:251)
at $anonfun$1.applyOrElse(<console>:10)
at $anonfun$1.applyOrElse(<console>:10)
at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)
... 33 elided
Kod z pliku CaseFunctions1.scala definiuje funkcję mającą typ ogólny PartialFunction, a w konsekwencji posiadającą metodę isDefinedAt. Za pomocą składni wyrażeń case można również utworzyć funkcję, która nie implementuje isDefinedAt. W przykładzie z pliku CaseFunctions2.scala kontekst wymaga funkcji typu String => String.
Plik CaseFunctions2.scala: val hello2: String => String = { case "en" => "Hello!" case "it" => "Ciao!" }
W konsekwencji metoda isDefinedAt nie zostaje dla tej funkcji wygenerowana, co można sprawdzić odwołując się do mechanizmu refleksji dostępnego na platformie JVM.
scala> :load CaseFunctions2.scala
Loading CaseFunctions2.scala...
hello2: String => String = <function1>
scala> hello1.getClass.getMethods.exists(_.toString.contains("isDefinedAt"))
res5: Boolean = true
scala> hello2.getClass.getMethods.exists(_.toString.contains("isDefinedAt"))
res6: Boolean = false
![]() | Specyfikacja języka Scala opisuje notację wykorzystującą ciąg klauzul case do tworzenia funkcji w punkcie 8.5. |
Plik CaseFunctions1.scala:
val hello1: PartialFunction[String,String] = {
case "en" => "Hello!"
case "it" => "Ciao!"
}

