Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala case类中的def与lazy val_Scala_Lazy Evaluation_Function - Fatal编程技术网

Scala case类中的def与lazy val

Scala case类中的def与lazy val,scala,lazy-evaluation,function,Scala,Lazy Evaluation,Function,我有一个我定义为case类的DAO对象 case class StudentDAO(id: Int) { def getGPA: Double = // Expensive database lookup goes here def getRank: Int = // Another expensive database operation and computation goes here def getScoreCard: File = // Expensive file loo

我有一个我定义为case类的DAO对象

case class StudentDAO(id: Int) {
  def getGPA: Double = // Expensive database lookup goes here
  def getRank: Int = // Another expensive database operation and computation goes here
  def getScoreCard: File = // Expensive file lookup goes here
}
我自然会做
getGPA
getRank
getScoreCard
def
s而不是
val
s,因为我不希望在使用它们之前计算它们

如果我将这些方法标记为
lazy val
s而不是
def
s,会对性能产生什么影响?我想让他们
lazy val
s的原因是:我不想每次为id为“I”的学生重新计算排名

我希望这不会被标记为重复,因为下面有几个问题主要是关于差异的:

这个问题主要是针对成本高昂的操作制定
方法
a
lazy val
的费用(CPU与内存之间的权衡),一个建议比另一个建议如何,为什么

编辑:谢谢你的评论@om nom nom。我应该更清楚我在找什么

我在这里读到:


对象的字符串表示形式将被缓存(请参见)。更准确地说,如果我将垃圾收集改为
lazy val
,而不是
def

对我来说似乎非常简单,那么我将考虑垃圾收集的影响:

我不希望他们在可能被计算之前就被计算出来 用过。 [...] 我不想每次为id为“I”的学生重新计算排名

然后使用
lazy val
,就是这样


def
用于每次调用的值可能更改时,通常是因为您传递了参数,
val
不会更改,但会立即计算。

对于“普通”引用类型(例如,
文件
)的
延迟val
具有在第一次计算时创建强引用的效果。因此,虽然它将避免对不变的值进行重新评估,但将计算出的值保留在内存中的成本是显而易见的


对于基本值(甚至是轻量级对象,如
文件
),这种内存开销通常不是什么问题(除非您在内存中持有大量
学生
对象)。但是,对于大量引用(例如,大型数据结构),最好使用弱引用、其他缓存方法,或者只按需计算值。

您希望听到什么?lazy val会让你多消耗10个字节和200个CPU周期?@om-nom-nom:不完全是。请参阅我的编辑:)因此将其设置为
def
而不是
lazy val
是有意义的,因为该值可能会更改?那么最好是一个
def
!对垃圾收集的影响如何?请查看我的编辑。如果值可能更改,则它肯定是一个
def
。一个
val
将被计算一次,就这样。有意义。假设该值不会更改,并且我想使用
lazy val
而不是
def
,那么对GC有什么影响?它将是您实例的一个属性,除非不再引用您的
StudentDAO
,否则它不会被垃圾收集。如果可以重新计算该值,但您希望保留计算值,除非GC需要内存,请查看
WeakReference