Scala 中的惰性验证和无限序列
Scala 中存在 Vals 和Lazy vals。 lazy 关键字更改 val 以延迟初始化。延迟初始化意味着每当一个对象创建看起来很昂贵时,lazy 关键字可以放在 val 之前。这使它具有在第一次使用时初始化的优势,即表达式入站不会立即评估,而是在第一次访问时评估一次。
例子:
// Scala program of Lazy val
// Creating object
object GFG
{
// Main method
def main(args:Array[String])
{
lazy val geek = {
println ("Initialization for the first time")
12
}
// Part 1
println(geek)
// Part 2
print(geek)
}
}
输出 :
Initialization for the first time
12
12
在上面的代码中,'geek' 是一个惰性 val,因此第一次访问它时,它返回
Initialization for the first time
12
但是第二次打印时,它只返回
12
因为它是一个缓存的结果。
当我们在 val 关键字之前使用惰性关键字时,会使用块表达式来初始化变量 - “geek”。为了在 Scala 中使用块,表达式序列包含在{ }中。因此,值“12”是块的值,赋值表达式的值是 Unit,在Java中实际上是一个 void 类型。
无限序列
Scala 的列表是序列。此外,这些列表是严格的序列,这意味着列表元素是预先构建的。但是也有非严格的序列,其中元素是根据要求构造的。通过连接 cons 单元创建一个列表。
有2个这样的情况:
12 ::Nil
在这里,con 单元格有一个值和空的尾列表。而这里的列表只是一个元素。
List[Int] = List(12)
12 : 22 : Nil
在这里,cons 单元格有一个值和另一个列表作为尾部。
List[Int] = List(22)
::符号是 cons(构造)运算符。我们调用cons运算符, Nil是一个列表。这就是列表的增长方式。
有 3 种方法可以创建这样的列表:
- 代码 1:
val geek = 6 ::23 ::45 ::Nil print(geek)
输出 :
List(6, 23, 45)
- 代码 2:
val geek = (6 ::(23 ::(45 ::Nil))) print(geek)
输出 :
List(6, 23, 45)
- 代码 3:
val geek = (((Nil.::(45)).::(23)).::(6)) print(geek)
输出 :
List(6, 23, 45)
例子 :
// Scala program to merge lists
// Creating object
object GFG
{
// Main method
def main(args:Array[String])
{
var a = 5
def fun() = {
a += 1;
a
}
lazy val geek = Stream.continually( fun() )
(geek take 10) foreach {
x => println(x)
}
}
}
输出 :
6
7
8
9
10
11
12
13
14
15
fun()方法被转换为函数。 Stream.continually()方法创建了一个无限流。它接受该函数,并且每当访问每个元素时,仅在那时调用 fun()函数来计算该元素。这种按需执行的函数称为Thunk ,一旦计算完成,它就会进入缓存以供进一步使用,这称为memoization 。