9.5. Using Closures

Problem

You want to pass a function around like a variable, and while doing so, you want that function to be able to refer to one or more fields that were in the same scope as the function when it was declared.

Solution

To demonstrate a closure in Scala, use the following simple (but complete) example:

package otherscope {

  class Foo {
    // a method that takes a function and a string, and passes the string into
    // the function, and then executes the function
    def exec(f:(String) => Unit, name: String) {
      f(name)
    }
  }

}

object ClosureExample extends App {

  var hello = "Hello"
  def sayHello(name: String) { println(s"$hello, $name") }

  // execute sayHello from the exec method foo
  val foo = new otherscope.Foo
  foo.exec(sayHello, "Al")

  // change the local variable 'hello', then execute sayHello from
  // the exec method of foo, and see what happens
  hello = "Hola"
  foo.exec(sayHello, "Lorenzo")

}

To test this code, save it as a file named ClosureExample.scala, then compile and run it. When it’s run, the output will be:

Hello, Al
Hola, Lorenzo

If you’re coming to Scala from Java or another OOP language, you might be asking, “How could this possibly work?” Not only did the sayHello method reference the variable hello from within the exec method of the Foo class on the first run (where hello was no longer in scope), but on the second run, it also picked up the change to the hello variable (from Hello to Hola). The simple answer is that Scala supports closure functionality, and this is how ...

Get Scala Cookbook now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.