Scala 函数字面量中的变量定义
Variable definition in Scala function literal
我想知道这段代码的结果
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 被 return 编辑为
hello
方法中的 return 值,分配到 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()
}
我想知道这段代码的结果
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 被 return 编辑为
hello
方法中的 return 值,分配到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()
}