2014年8月4日
等价的
Stateless Future支持发生器1。发生器功能类似Scala的for
/yield
推导式,但发生器比for
/yield
推导式更灵活。你可以用Stateless Future生成很复杂的惰性求值容器。
用法
首先,想好你的容器中的元素类型,创建一个Generator:
import com.qifun.statelessFuture.util.Generator
val gen = Generator[Int] // 创建用来生成Seq[Int]的发生器
然后创建gen.Future
:
val genFuture = gen.Future {
for (i <- gen.futureSeq(0 until 3)) {
gen(i * i).await // 生成容器中的一项,值是i*i
}
}
gen.Future
是一种特殊的Future
,专门用于发生器。gen.Future
与com.qifun.statelessFuture.Future的类型有微妙的区别,相互之间不能隐式转换。gen.futureSeq
则类似上一节中介绍的futureSeq,可以配合gen.Future
使用。
最后把genFuture
转换成gen.OutputSeq
:
val genSeq: gen.OutputSeq = genFuture
gen.OutputSeq
派生于Seq
。genSeq
是个惰性求值的容器,内容是Seq(0, 1, 4, 9)
。
等价的for
/yield
推导式
这种惰性求值容器也可以用普通的for
/yield
推导式生成:
val forYieldSeq: Seq[Int] =
for (i <- (0 until 10).view) yield { // view后缀使得for语句返回支持惰性求值的SeqView,而不是普通的Seq
i * i
}
forYieldSeq
也是个惰性求值的容器,内容也是Seq(0, 1, 4, 9)
。
进阶用法
虽然上例中的for
/yield
也能涵盖发生器最简单的用法,但是除此之外,发生器中还可以容纳任意控制语句,这种进阶用法就没办法靠for
/yield
实现了。
import com.qifun.statelessFuture.util.Generator
val gen = Generator[Int]
val genSeq2: gen.OutputSeq = gen.Future {
gen(-1).await
for (i <- gen.futureSeq(0 until 3)) {
gen(i * i).await
if (i == 2) {
gen(i).await
gen(i).await
gen(i).await
}
}
gen(-2, -3, -2).await // 在一行代码中生成多个元素
}
genSeq2
的值是Seq(-1, 0, 1, 4, 2, 2, 2, 9, -2, -3, -2)
,这样灵活的控制流程,比for
/yield
功能强。
(待续)
- 栏目
- 程序设计 (7)