Scala闭包疑问:为何第三次调用p()返回10而非11?
问题解析:Scala闭包中第三个输出为10的原因
先看原代码:
class A(var x : Int) { def f() : () => Int = { var y : Int = 1 () => {y = y + 2; y + x} } } object ClosureM2 { def main(args : Array[String]) : Unit = { var a = new A(2) var p = a.f() println(p()) a.x = 3 println(p()) a = new A(4) println(p()) p = a.f() println(p()) } }
核心原因是闭包捕获的是实例引用,而非变量a的引用,执行过程拆解:
- 初始创建
A(2)实例赋值给a,调用a.f()生成闭包p。p绑定了两个对象:f内的局部变量y(初始1),以及当前a指向的x=2的A实例(注意:是实例本身,不是变量a)。 - 第一次调用
p():y从1变为3,计算3+2=5,输出5,此时y更新为3。 - 修改
a.x=3:这是修改旧A实例的x值(a此时仍指向它),第二次调用p():y从3变为5,计算5+3=8,输出8,y更新为5。 - 执行
a = new A(4):变量a指向新的x=4的A实例,但p绑定的还是旧实例(它的x还是3)。第三次调用p():y从5变为7,计算7+3=10,输出10——这就是为什么不是11,因为闭包用的是旧实例的x,不是新实例的。 - 最后
p = a.f():p变成新实例生成的闭包,绑定新实例的x=4和新的y=1,调用p()得到3+4=7,输出7。
内容的提问来源于stack exchange,提问作者IGG
相关产品推荐
相关产品推荐

