Я прокомментировал случай контрольных структур. Позвольте мне прокомментировать замыкания как объекты. Подумайте, что происходит, когда вы вызываете метод объекта; он имеет доступ не только к списку аргументов, но и к полям объекта. То есть метод / функция закрывается над полями. Это ничем не отличается от «голой» функции (т. Е. Не объектного метода), которая закрывает переменные в области видимости. Однако синтаксис объекта обеспечивает хороший механизм абстракции и модульности.
Например, я мог бы написать
case class Welcome(message: String) {
def greet(name: String) = println(message + ", " + name)
}
val w = Welcome("Hello")
w.greet("Dean")
против
val message = "Hello"
val greet = (name: String) => println(message + ", " + name)
greet("Dean")
На самом деле, в этом примере я мог бы удалить ключевое слово case из Welcome, чтобы сообщение не становилось полем, но значение все еще находится в области видимости:
class Welcome2(message: String) { // removed "case"
def greet(name: String) = println(message + ", " + name)
}
val w = new Welcome2("Hello") // added "new"
w.greet("Dean")
Это все еще работает! Теперь greet закрывает значение входного параметра, а не поля.
var welcome = "Hello"
val w2 = new Welcome2(welcome)
w2.greet("Dean") // => "Hello, Dean"
welcome = "Guten tag"
w2.greet("Dean") // => "Hello, Dean" (even though "welcome" changed)
Но если класс напрямую ссылается на переменную во внешней области видимости,
class Welcome3 { // removed "message"
def greet(name: String) = println(welcome + ", " + name) // reference "welcome"
}
val w3 = new Welcome3
w3.greet("Dean") // => "Guten tag, Dean"
welcome = "Buon giorno"
w3.greet("Dean") // => "Buon giorno, Dean"
Имеет смысл?