Scala 是否使用常量 Return 值优化方法定义?

Does Scala Optimize Method Definition with a Constant Return Value?

Scala 是否将具有常量 return 值的方法定义优化为 val?

class MyClass extends MyTrait {
  override def getMap(): Map[Int, String] = Map(1 -> "one")
}

trait MyTrait {
  def getMap() : Map[Int, String]
}

优化到?

class MyClass extends MyTrait {
  val getMap: Map[Int, String] = Map(1 -> "one")
}

这样可以让程序员在必要时选择使用动态定义。

不,不是。 valdef 有不同的契约,在语言上有不同的后果。路径相关类型不能基于 def,而 def 可以被 val 覆盖,反之则为假。

具体来说,由 val 编辑的值 return 保证每次都相同,一旦初始化,而 def 每次都可以 return 不同的值它被称为。

在调用文字的情况下,人们可能会想到优化,但在您的代码中并非如此。 Map(1 -> "one") 是一个方法调用,每次都可以 return 不同的值(就像 def)。

哦,小细节,如果你感兴趣的话:valdef 都是通过方法调用实现的,尽管前者从字段中读取,而后者不是。

不,不是。事实上,scalac 做不到这一点。这只能由 VM 完成,它在运行时具有有关程序的完整信息。原因如下。

首先,一些 class SubClass 可以扩展 MyClass 并用另一种方法覆盖 getMap。如果 scalac 确实实施了此优化,SubClass 将在其 superclass 中有一个空的虚假字段,并增加占用空间。

其次,scalac不知道Map是如何实现的。如果 Map 工厂有副作用,这种优化会阻止它们在每次调用 getMap 时执行。这改变了程序的语义。有一些 early attempts to overcome this,并为编译器保留更多信息以便能够对其进行分析,但您应该意识到,这样的优化仍然可能会破坏依赖注入和模拟框架所依赖的反射功能。

最后,不清楚什么时候这才是真正的优化。如果 return 表达式真的很便宜(例如一个数字),它会增加 class 的内存占用以缓存几乎可以毫不费力地计算的值。

顺便说一句,您描述的不是静态函数定义,而是具有常量 return 值 .

方法定义