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

Scala中变量为何在调用后才计算?代码输出差异疑问

为什么Scala程序保留/移除最后一行的r会有不同输出?

这是Scala集合惰性求值(lazy evaluation)的典型表现,核心原因在于filterKeys返回的不是一个立即计算好的新Map,而是一个惰性视图——它不会立刻执行你写的过滤逻辑,只有当你实际使用这个视图的时候,才会去遍历原集合并执行过滤函数。

我们来拆解两种场景的执行过程:

场景1:保留最后一行的r

当代码最后保留r时,Scastie的运行机制会自动评估并尝试显示最后一个表达式的结果(也就是r的值)。这时候就触发了filterKeys的实际执行:

  • 程序会遍历原Mapm的每一个键,逐个执行你定义的过滤函数;
  • 遇到键1、2、3时,因为k>3不成立,所以会执行println(k),同时尝试把对应的键值对加到mm中;
  • 你看到的(end of program,Map())是在r被触发之前打印的——这时候mm还没被修改,所以显示为空;之后执行r的计算时,才会输出1、2、3,此时mm其实已经有值了,但之前的println已经输出过,所以看不到更新后的mm。

场景2:移除最后一行的r

当你去掉r之后,整个程序里再也没有任何地方实际使用filterKeys返回的这个惰性视图。Scala的惰性集合非常“懒”——只要没人用它,它就不会去执行任何遍历或过滤操作:

  • 过滤函数里的println(k)和mm += ...完全不会被执行;
  • 程序执行到println("end of program", mm)就结束了,mm一直是空的,所以输出只有那一行。

小提示

如果想让filterKeys立刻执行(不管之后用不用结果),可以把结果转换成严格集合,比如:

val r = m.filterKeys { k =>
  if(k>3) true else { println(k); mm += (k -> m(k)); false }
}.toMap // 转换成严格的Map,触发立即计算

内容的提问来源于stack exchange,提问作者BAE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:48:16