I'm wondering the result of the piece of code
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()
}
}
}
Why is the variable t
in hello
function is only assigned once,and the result will be 6, 9, 12....
I guess this may be related to closure property,but why var t = 3
is only executed once?
This is not usual functional Scala code, where immutables and vals are prefered over mutability. The style reminds me of Javascript, where things like this are seen very often. Yes, you are correct, this is related to the closure:
hello
method defines a scope. In this scope there are two things existing: the t
variable and the lambda (the function literal () => {...}
)hello
method, assigned into the test
variable and repeatedly executed by the while
loopt
variable, which is captured in it.The variable exists in the scope of hello
, but as it is captured by the lambda, is it is the same variable used again and again. It is not the hello scope which gets executed from the while
loop, rather the lambda body. The hello
is executed only once to create the t
variable and the lambda.
Expanding the hello
definition might help you understand this easier:
val test = {
var t = 3
() => {
t = t + 3
println(t)
}
}
while (true) {
Thread.sleep(1000)
test()
}
This could be transformed to following code with the same functionality, only the t
scope would be expanded so that even the code other than the lambda can see it:
var t = 3
val test = () => {
t = t + 3
println(t)
}
while (true) {
Thread.sleep(1000)
test()
}