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
Plik MakeGreeter.scala:
def makeGreeter(greeting: String) = {
var counter = 0
() => {
counter = counter + 1
greeting + " " + counter
}
}
