convert
是否可以使用上面的签名来实现convert(computeComplexNumber)
方法,条件是在调用Await.result(convert(computeComplexNumber), 5.seconds)()
时,除非执行此操作,否则什么都不会打印出来
g <- erdos.renyi.game(10,.3)
g <- set_vertex_attr(g,"a", index = V(g), 1)
g <- set_vertex_attr(g,"b", index = V(g), 1)
g <- set_vertex_attr(g,"c", index = V(g), 1)
g
l<- c("a", "b", "c")
for (i in l){
g2<-delete_vertex_attr(g, i)
}
g2
答案 0 :(得分:10)
如果没有在convert
内部进行封锁,我看不到有任何办法。如果不调用Future[X]
,根本无法在convert
内部获得f
的实例。但是一旦调用f
,Future { ... }
就会急切地开始使用println
来评估该块,并产生输出。
您可能想看看scalaz.concurrent.Task
。
答案 1 :(得分:2)
如果要将() => Future[Int]
转换为() => Int
,则必须等待Future
的结果,如下所示:
def convert(f: () ⇒ Future[Int]): Future[() ⇒ Int] =
Future{
() => Await.result(f(), Duration.Inf)
}
然后
val f = convert(computeComplexNumber) // Get Future
val g = Await.result(f, Duration.Inf) // Get Function
g() // Call function
在您致电g
之前,不会显示输出。
这个问题的核心是这个函数签名:
def convert(f: () ⇒ Future[Int]): Future[() ⇒ Int]
(在释义中)还有一个要求
f
在调用返回的函数之前不会被调用
此外,我假设结果中的Int
是参数中Future
返回的值,而不仅仅是一些随机数!
输入函数的返回类型为Future[Int]
,输出函数的返回类型为Int
。第一个是异步结果,第二个是同步结果。因此,任何解决方案都必须从异步Future[Int]
转换为同步Int
。这意味着Await.result
或类似名称。
还要求在执行输出功能之前不执行输入功能。这意味着必须在返回的函数内部调用它 ,这又意味着必须在返回的函数内部调用Await.result
。
上述解决方案具有问题所需的convert
功能签名。在执行f
返回的函数之前,它也不会调用convert
,这是另一个要求。
此convert
的实现没有阻塞;它立即返回一个Future
值。它不调用f
,而只是返回一个函数。
在一个函数内部阻塞或一个函数调用另一个函数的含义存在争议。阻塞和调用是函数执行期间发生的过程。因此,对这些在“函数内部”发生的事物的明智定义是,它们发生在函数入口点的执行与函数出口点的执行之间。使用此定义,很明显解决方案不会在函数内部阻塞或在函数内部调用f
。
提问者还评论说Await.result
不应在任何地方被调用。不幸的是,如上所述,这是不可能的,因为要求是将异步结果转换为同步结果。
答案 2 :(得分:-1)
也许这样可以工作:
def computeComplexNumber: () => Future[Int] = () =>
Future {
delay(4.seconds.fromNow)
println("Computing complex number ...")
Int.MaxValue
}
def convert(f: () => Future[Int]): Future[() => Int] = {
f().map( m => () => m)
}
def delay(dur:Deadline) = {
Try(Await.ready(Promise().future, dur.timeLeft))
}