我想知道代码的结果
object localTest {
def hello = {
var t = 3
() => {
t = t + 3
println(t)
}
}
}
object mainObj {
def main(args: Array[String]): Unit = {
val test = localTest.hello
while (true) {
Thread.sleep(1000)
test()
}
}
}
为什么hello
函数中的变量t
只分配一次,结果会是6、9、12…
我想这可能和闭包属性有关,但为什么var t = 3
只执行一次呢?
这不是通常的函数Scala代码,在这里免疫表和val比可变性更受欢迎。这种风格让我想起了Javascript,在那里经常可以看到这样的东西。是的,你是对的,这与关闭有关:
hello
方法定义了一个范围。在这个作用域中存在两个东西:t
变量和lambda(函数文字() => {...}
(- lambda作为返回值从
hello
方法返回,分配给test
变量,并由while
循环重复执行 - lambda正在更改其中捕获的
t
变量
变量存在于hello
的作用域中,但当它被lambda捕获时,它是反复使用的同一个变量吗。它不是从while
循环执行的hello作用域,而是lambda主体。hello
只执行一次以创建t
变量和lambda。
扩展hello
的定义可能会帮助您更容易地理解这一点:
val test = {
var t = 3
() => {
t = t + 3
println(t)
}
}
while (true) {
Thread.sleep(1000)
test()
}
这可以转换为以下具有相同功能的代码,只有t
范围会被扩展,这样即使是lambda之外的代码也可以看到它:
var t = 3
val test = () => {
t = t + 3
println(t)
}
while (true) {
Thread.sleep(1000)
test()
}