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

Scala中使用val定义函数字面量的代码示例解析

解析Scala中两种val定义函数字面量的行为差异

让我结合你给出的Scala交互代码,拆解这两种函数字面量定义的执行逻辑和行为差异:

scala> val double = (i: Int) => {
     | println("I am here")
     | i * 2
     | }
double: Int => Int = $$Lambda$1090/773348080@6ae9b2f0
scala> double(4)
I am here
res22: Int = 8
scala> val evenFunc: (Int => Boolean) = {
     | println("I am here");
     | (x => x % 2 == 0)
     | }
I am here
evenFunc: Int => Boolean = $$Lambda$1091/373581540@a7c489a
scala> double
res23: Int => Int = $$Lambda$1090/773348080@6ae9b2f0
scala> evenFunc
res24: Int => Boolean = $$Lambda$1091/...

1. 第一种:直接赋值匿名函数字面量 (val double = (i: Int) => { ... })

这种写法是把一个匿名函数字面量直接绑定到变量double。这里的花括号是函数字面量的函数体,里面的代码只有在调用这个函数的时候才会触发执行:

  • 当你定义double时,Scala只是创建了一个实现Int => Int trait的Lambda实例,函数体里的println("I am here")和i * 2都不会执行,所以定义阶段没有任何控制台输出。
  • 只有当你调用double(4)时,才会进入函数体执行逻辑:先打印"I am here",再计算4 * 2并返回结果,这时候你才会看到输出,同时得到返回值8。

2. 第二种:代码块返回函数字面量 (val evenFunc: (Int => Boolean) = { ... })

这种写法的右边是一个普通的Scala代码块,而不是直接的函数字面量。这个代码块会在变量初始化(也就是定义evenFunc的瞬间)立即执行,代码块的最后一行表达式的结果会被赋值给evenFunc:

  • 当你定义evenFunc时,Scala会先执行代码块里的所有语句:先打印"I am here",然后执行最后一行的(x => x % 2 == 0)创建一个Lambda实例,把这个实例赋值给evenFunc。所以定义阶段就直接输出了"I am here"。
  • 之后你调用evenFunc(比如evenFunc(2))时,只会执行这个Lambda的核心逻辑(判断输入是否为偶数),不会再执行之前的打印语句——因为打印语句是初始化代码块的一部分,在变量定义时就已经执行完毕了。

核心差异总结

  • 执行时机不同:
    • 第一种定义:函数体代码仅在调用double(参数)时执行,定义变量时不会触发。
    • 第二种定义:代码块在evenFunc初始化时立即执行,后续调用函数不会再触发这段初始化代码。
  • 代码块的角色不同:
    • 第一种的花括号是函数字面量的一部分,属于函数被调用时要执行的核心逻辑。
    • 第二种的花括号是独立的初始化代码块,它的作用是生成最终要赋值给变量的函数字面量,代码块里的其他语句(比如println)都是初始化时产生的副作用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:40:33