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

Scala中Val、def、lazy val的实例化顺序及代码输出解析

Scala中val、def、lazy val的执行逻辑详解(附代码输出分析)

先把待分析的代码贴出来:

def deflazyval() : Unit = {
  lazy val l : Int ={print("l") ; 5}
  def      d : Int ={print("d") ; 7}
  val      v : Int ={print("v") ; 3}
  
  var s : Int = d
  s += l
  s += v
  s += l
  s += d
}

先搞懂三个核心元素的特性

  • def(方法):每次被调用时都会完整执行一遍代码块,返回新的计算结果,不存在缓存。
  • val(普通值):在定义的那一刻就会立即执行代码块,算出结果后永久固定,后续引用直接用缓存的结果,不会再跑代码块。
  • lazy val(懒加载值):定义时完全不执行代码块,第一次被引用时才会执行代码块并缓存结果,之后再引用就直接用缓存值,不会重复执行。

逐步骤拆解执行过程

调用deflazyval()后,整个流程的执行顺序和输出变化如下:

  1. 变量定义阶段

    • 声明lazy val l:只是注册了这个变量,代码块{print("l") ; 5}完全不执行,无任何输出。
    • 声明def d:只是定义了方法逻辑,方法体{print("d") ; 7}不执行,无输出。
    • 声明val v:立即执行代码块,打印v,并把结果3赋值给v,此时输出内容为v。
  2. 变量s的操作阶段

    • var s : Int = d:调用方法d,执行其代码块,打印d,返回7给s。此时输出变为vd。
    • s += l:第一次引用lazy val l,执行其代码块,打印l,返回5,s更新为7+5=12。此时输出变为vdl。
    • s += v:引用val v,直接用之前缓存的3,不会重复执行代码块,无新输出,s更新为12+3=15。输出仍为vdl。
    • s += l:再次引用lazy val l,直接用第一次缓存的5,不执行代码块,无新输出,s更新为15+5=20。输出还是vdl。
    • s += d:再次调用方法d,执行其代码块,打印d,返回7,s更新为20+7=27。此时输出最终变为vdld。

为什么输出是vdld?

  • v是普通val,定义时直接执行打印,是第一个输出。
  • 第一次调用d方法,执行打印,输出追加d。
  • 第一次引用lazy val l,触发打印,输出追加l。
  • 后续引用v和l都用缓存值,不会产生新输出。
  • 第二次调用d方法,再次执行打印,输出追加d,最终得到vdld。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 02:55:34