Scala 2.13.8中匿名函数为何未显示Function2类型的技术问询
Scala 2.13.8中匿名函数的类型显示困惑
最近在学习《Functional Programming in Scala》时,遇到了一个关于匿名函数类型显示的问题,想和大家聊聊:
书中示例与实际运行的差异
首先看书中第24页的代码示例:
书中给出的匿名函数代码:
scala> (x:Int,y:Int)=> x<y书中显示的输出结果是:
res3: (Int,Int)=> Boolean = <Function2>
但我在Scala 2.13.8版本的REPL中运行这段代码,得到的输出却是:
val res3: (Int, Int) => Boolean = $Lambda$883/1341083542@7c871ce4
同样,把匿名函数赋值给变量的场景:
scala> val lessThan = (x:Int,y:Int)=> x<y
实际输出也没有显示Function2相关标识:
val lessThan: (Int, Int) => Boolean = $Lambda$841/566447096@559e3f67
不过当我显式实现Function2特质时,输出就和书中的预期一致了:
scala> val lessThan2 = new Function2[Int,Int,Boolean] { | def apply(a:Int, b:Int)= a<b }
输出结果:
val lessThan2: (Int, Int) => Boolean = <function2>
为什么会有这种差异?
其实这是Scala版本迭代带来的底层实现变化:
- 这本书基于的是较早的Scala版本(比如Scala 2.10或更早),在那些版本里,匿名函数会被直接编译为
FunctionN特质的匿名内部类,所以REPL会显示<Function2>这样的标识。 - 从Scala 2.11开始,官方引入了Lambda MetaFactory优化,匿名函数会被编译成Java的lambda表达式,而非传统的
FunctionN匿名内部类。这时候REPL显示的$Lambda$xxx就是Java lambda的内部命名形式,而非Scala原生的FunctionN对象标识。
不过不用担心,从类型语义上来说,(Int, Int) => Boolean和Function2[Int, Int, Boolean]是完全等价的——前者就是后者的语法糖。你可以在REPL里验证这一点:执行lessThan.isInstanceOf[Function2[Int, Int, Boolean]],会返回true,说明这个匿名函数本质上还是属于Function2类型体系。
内容的提问来源于stack exchange,提问作者GPopat
相关产品推荐
相关产品推荐

