【发布时间】:2013-07-15 21:34:04
【问题描述】:
我有一个抽象的特征,对计算有一些要求,然后是对这些计算结果的一些函数。我想让这个特性保持简单,以便于理解和测试。
trait Calculator {
def hardToCalculate1: Int
def hardToCalculate2: Int
def hardToCalculate3: Int
def result1 = hardToCalculate1 + hardToCalculate2
def result2 = hardToCalculate2 + hardToCalculate3
def result3 = hardToCalculate1 + hardToCalculate3
}
当我实例化一个Calculator 时,我将使用Futures 来计算那些hardToCalculate 值。假设它们看起来像这样:
def f1 = future {
println("calculating 1")
1
}
def f2 = future {
println("calculating 2")
2
}
def f3 = future {
println("calculating 3")
3
}
所以,我可以像这样构造一个Future[Calculator]:
val myCalc = for {
m1 <- f1
m2 <- f2
m3 <- f3
} yield new Calculator {
lazy val hardToCalculate1 = m1
lazy val hardToCalculate2 = m2
lazy val hardToCalculate3 = m3
}
那么,我可能会像这样使用myCalc:
myCalc onComplete {
case Success(calc) => println("Result: " + calc.result1)
}
但是当我这样做时,我得到了这个:
calculating 1
calculating 2
calculating 3
Result: 3
我只想在我正在进行的计算确实需要这些期货时才执行它们。尽管我用lazy val 声明了hardToCalculates,但所有三个都是在执行Future[Calculator].onComplete 时计算的。
一种方法是这样的:
val calculator = new Calculator {
lazy val hardToCalculate1 = Await.result(f1, 10 seconds)
lazy val hardToCalculate2 = Await.result(f2, 10 seconds)
lazy val hardToCalculate3 = Await.result(f3, 10 seconds)
}
println("result: " + calculator.result1)
这会产生我想要的:
calculating 1
calculating 2
result: 3
但现在我有所有Await 阻塞。我真正想要的是一个Future[Calculator],它将以一种懒惰的方式执行期货。如果不将 Futures 引入我的 Calculator 特征中,这可能吗?关于如何在这里获得我想要的东西还有其他建议吗?
【问题讨论】: