我是 scala 和大多数函数式语言的新手,我目前正在尝试计算一个数字。我已经写了代码:
lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int
我想知道如果我将 scala val 声明为惰性,它会不会在我调用时评估整个理解factors.head
?
我是 scala 和大多数函数式语言的新手,我目前正在尝试计算一个数字。我已经写了代码:
lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int
我想知道如果我将 scala val 声明为惰性,它会不会在我调用时评估整个理解factors.head
?
你的factors
变量是懒惰的;for
理解不是。当您第一次访问factors
时,您的for
理解力将得到全面评估。
在 Scala 中,for
理解只是flatMap
、map
和withFilter
方法调用的糖。因此,如果您的支持数据结构是严格的(例如Range
- 这是您正在使用的),您的for
理解也将是严格的。如果数据结构是惰性的(例如Stream
),那么for
理解也是。
观察差异:
scala> val number = 50
number: Int = 50
scala> lazy val factors = for(int <- 2 until math.ceil(math.sqrt(number)).toInt if number%int == 0) yield int
factors: scala.collection.immutable.IndexedSeq[Int] = <lazy>
scala> factors.head
res5: Int = 2
scala> factors
res6: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 5)
scala> lazy val factors = for(int <- Stream.range(2, math.ceil(math.sqrt(number)).toInt - 1) if number%int == 0) yield int
factors: scala.collection.immutable.Stream[Int] = <lazy>
scala> factors.head
res7: Int = 2
scala> factors
res8: scala.collection.immutable.Stream[Int] = Stream(2, ?)
不,这是完全不同的事情:lazy
意味着该值是在您第一次访问它时计算的。如果你想对集合进行惰性计算,你应该使用Stream
或使用视图。AStream
可以使用view
.