11.8. Funkcje częściowe

Plik PartialFunctions1.scala zawiera definicję funkcji multilingualHello, przyjmującej jeden argument typu String, określający język, w jakim ma być zwrócona odpowiedź i zwracający pozdrowienie w tym języku.

Plik PartialFunctions1.scala:
object multilingualHello extends Function1[String,String] {
  def apply(lang: String): String =
    if (lang == "en") "Hello!"
    else if (lang == "it") "Ciao!"
    else throw new IllegalArgumentException(
      "I do not know the language: "+lang)
}

Funkcja multilingualHello potrafi zwrócić odpowiedź dla dwóch rodzajów argumentów (dla dwóch języków). Dla innych argumentów powoduje zwrócenie wyjątku. Poniższe polecenia pokazują przykładowe wywołania funkcji multilingualHello.

scala> multilingualHello("en")
res0: String = Hello!

scala> multilingualHello("it")
res1: String = Ciao!

scala> multilingualHello("fr")
java.lang.IllegalArgumentException: I do not know the language: fr
  at multilingualHello$.apply(PartialFunctions1.scala:5)
  ... 33 elided

Gdyby istniała możliwość „zapytania” funkcji, czy jest w stanie obsłużyć konkretny zestaw argumentów, to można by wywoływać funkcję tylko dla tych argumentów, które jest ona w stanie obsłużyć, bez obawy uzyskania w rezultacie wyjątku. W Scali jest to możliwe przy użyciu tak zwanych funkcji częściowych. Plik PartialFunctions2.scala zawiera zmodyfikowaną definicję funkcji zwracającej pozdrowienie w różnych językach.

Plik PartialFunctions2.scala:
object multilingualHello2 extends PartialFunction[String,String] {
  def apply(lang: String): String =
    if (lang == "en") "Hello!"
    else if (lang == "it") "Ciao!"
    else throw new IllegalArgumentException(
      "I do not know the language: "+lang)
  def isDefinedAt(lang: String): Boolean =
    if (lang == "en" || lang == "it") true else false
}

Funkcja rozszerza PartialFuncion[String,String]. Klasa PartialFunction reprezentuje funkcje częściowe. Takie funkcje przyjmują zawsze jeden argument. Oprócz metody apply, definiują dodatkowo metodę isDefinedAt, mającą taką samą listę parametrów, jak apply. Metoda isDefinedAt zwraca wartość logiczną. Powinna zwracać wartość true dla tych argumentów, dla których apply potrafi zwrócić prawidłowy wynik. Natomiast dla innych argumentów powinna zwrócić false.

W przypadku obiektu multilingualHello2 metoda apply umie zinterpretować argumenty wejściowe będące łańcuchami znaków „en” i „it”. Implementacja metody isDefinedAt dla tych właśnie argumentów zwraca wartość logiczną true, a dla innych argumentów zwraca wartość false.

Mając do dyspozycji funkcję częściową, można za pomocą wywołania metody isDefinedAt „zapytać” ją, czy jest w stanie obsłużyć konkretny argument. Ilustrują to poniższe przykłady.

scala> multilingualHello2.isDefinedAt("en")
res3: Boolean = true

scala> multilingualHello2("en")
res4: String = Hello!

scala> multilingualHello2.isDefinedAt("it")
res5: Boolean = true

scala> multilingualHello2("it")
res6: String = Ciao!

scala> multilingualHello2.isDefinedAt("fr")
res7: Boolean = false

Scala umożliwia zastosowanie specjalnej składni, która może być zastosowana do tworzenia funkcji częściowych, a która nie wymaga bezpośredniej implementacji metod apply i isDefinedAt. Ta składnia jest przedstawiona w punkcie 14.15. Specyfikacja języka Scala opisuje klasę PartialFunction w punkcie 12.3.3.

Język programowania Scala Wydanie 2. Copyright © Grzegorz Balcerek 2016

Licencja Creative Commons

Ten utwór jest dostępny na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowe.

Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.