You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 23:45:42