11.6. Domknięcia

Funkcje „pamiętają” kontekst, w jakim zostały utworzone i mogą odwoływać się do zmiennych, do których miały dostęp w momencie utworzenia. Poniższy przykład pokazuje metodę makeGreeter, która tworzy funkcję zwracającą łańcuch znaków złożony z przekazanej metodzie makeGreeter wartości uzupełnionej o liczbę powiększaną przy każdym wywołaniu funkcji.

Plik MakeGreeter.scala:
def makeGreeter(greeting: String) = {
  var counter = 0
  () => {
    counter = counter + 1
    greeting + " " + counter
  }
}

W poniższym poleceniu, utworzona wewnątrz metody makeGreeter funkcja anonimowa, zostaje przypisana do wartości hello.

scala> :load MakeGreeter.scala
Loading MakeGreeter.scala...
makeGreeter: (greeting: String)() => String

scala> val hello = makeGreeter("Hello")
hello: () => String = <function0>

Kolejne polecenia pokazują kilka wywołań utworzonej funkcji.

scala> hello()
res0: String = Hello 1

scala> hello()
res1: String = Hello 2

Można zauważyć, że łańcuch znaków zwracany przez funkcję jest za każdym razem inny. Funkcja, w momencie jej utworzenia, miała dostęp do zmiennej lokalnej counter z metody makeGreeter. Mimo że metoda makeGreeter zakończyła swoje działanie, funkcja nadal może korzystać z dostępu do tej zmiennej. Kolejne polecenie pokazuje utworzenie kolejnej funkcji za pomocą metody makeGreeter.

scala> val hi = makeGreeter("Hi")
hi: () => String = <function0>

Obie utworzone funkcje mogą być wywoływane niezależnie i obie korzystają ze swojej własnej kopii zmiennej counter.

scala> hi()
res2: String = Hi 1

scala> hello()
res3: String = Hello 3

scala> hi()
res4: String = Hi 2

scala> hello()
res5: String = Hello 4

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.