Scala是否使用常量返回值优化方法定义到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")
}
这样可以让程序员在必要时选择使用动态定义。
答案 0 :(得分:6)
不,它没有。 val
和def
有不同的合同,并在语言中产生后果。路径相关类型不能基于def
,而def
可能会被val
覆盖,反之亦然。
具体来说,val
返回的值每次初始化时都保证相同,而def
每次调用时都会返回不同的值。
考虑到调用文字的情况,可以考虑优化,但在代码中并非如此。 Map(1 -> "one")
是一个方法调用,每次都可以返回不同的值(就像def
)。
哦,小细节,如果您感兴趣:val
和def
都是通过方法调用实现的,虽然前者从字段读取,而后者不是。< / p>
答案 1 :(得分:6)
不,它没有。事实上,scalac
无法做到这一点。这只能由VM完成,VM在运行时具有有关程序的完整信息。这就是原因。
首先,某些课程SubClass
可以使用其他方法扩展MyClass
并覆盖getMap
。如果scalac
确实实现了此优化,则SubClass
将从其超类中获得一个空虚假字段,并增加占用空间。
其次,scalac
不知道如何实施Map
。如果Map
工厂有副作用,则此优化会阻止每次调用getMap
时执行。这改变了程序的语义。有一些early attempts to overcome this,并保留更多信息供编译器分析,但你应该知道,这样的优化仍然可能会破坏依赖注入和模拟框架所依赖的反射特性。
最后,目前尚不清楚这何时是真正的优化。如果返回表达式真的很便宜(例如一个数字),它会增加类的内存占用,以缓存一个几乎不费力就可以计算的值。
顺便说一下,你所描述的不是静态函数定义,而是具有常量返回值的方法定义。