Scala函数文本中的变量定义



我想知道代码的结果

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()
}

最新更新