scala - lambda () => 1 是否会在每次作为参数传递时在运行时创建对象?

标签 scala lambda jvm-bytecode

我的理解是,所有非捕获 lambda 都不需要在使用站点创建对象,因为可以将其创建为静态字段并重用。原则上,构成类方法调用的 lambda 也是如此——只有字段是非静态的。我从来没有真正尝试过更深入地研究它。现在我正在查看字节码,在封闭类中看不到字节码,也不知道在哪里看?我看到 lambda 工厂与 Java 中的不同,所以这应该有一个明确的答案——至少对于给定的 Scala 版本。
我的动机很简单:分析非常耗时。引入方法值(或者一般来说,lambdas 只捕获封闭对象的状态)作为私有(private)类字段比内联编写它们更不干净,而且工作量更大,而且通常不是好的代码。但是当编写已知(很有可能)成为热点的区域时,这是一个非常简单的优化,可以立即执行,而不会对程序员的时间产生任何实际影响。但是,如果无论如何都没有创建新对象,那是没有意义的。
举个例子:

def alias(x :X) = aliases.getOrElse(x, x)

def alias2(x :X) = aliases.getOrElse(x, null) match {
    case null => x
    case a => a
}
第一个 lambda (a Function0 ) 必须是一个新对象,因为它捕获方法参数 x ,而第二个返回一个常量( null ),因此实际上不必这样做。它也没有污染命名空间的私有(private)类字段那么困惑(IMO),但我希望能够确定 - 或者有一种方法可以轻松确认我的期望。

最佳答案

以下证明至少在某些时候,答案是否定的:

scala 2.13.4> def foo = () => 1
def foo: () => Int

scala 2.13.4> foo eq foo
val res5: Boolean = true

关于scala - lambda () => 1 是否会在每次作为参数传递时在运行时创建对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65386762/

相关文章:

arrays - Scala 将 IndexedSeq[AnyVal] 转换为 Array[Int]

c++ - 如何编写丢弃其参数的通用可变参数 lambda?

c# - 如何在linq中加入连续的日期范围

java - 为什么CgLib BeanCopier中有一个无用的(在我看来)dup2

java - 使用ASM进行字节码分析

html - 在 Play Framework 2.3 中生成指向 Controller 操作的链接

generics - 如何定义匿名泛型 Scala 函数?

json - 运行脚本时数据不刷新(NodeJs Lambda Alexa Skill)

jvm-bytecode - 读取和显示 Java .class 版本的工具

scala - 使用框架 REST 进行基本身份验证和 SSL